CoppeliaSim是一款基于分布式控制架构,具有集成开发环境的机器人仿真器。每个对象/模型都可以通过内嵌脚本、插件、ROS节点、BlueZero节点、远程API客户端或定制的解决方案进行单独控制。这使得CoppeliaSim非常通用和理想的应用于多机器人。控制器可以使用C/C++、Python、Java、Lua、Matlab、Octave或Urbi编写。
CoppeliaSim的一些应用:
CoppeliaSim可以作为一个独立的应用程序使用,也可以很容易地嵌入到主客户端应用程序中,其占用空间小和复杂的API使CoppeliaSim成为嵌入高级应用程序的理想候选者。集成的Lua脚本解释器使CoppeliaSim成为一个非常通用的应用程序,用户可以自由地组合低/高级功能以获得新的高级功能。
…
更多功能包括:
CoppeliaSim版本格式定义如下:
Version X.Y.Z (rev. W)
CoppelisSim V4.1.0(2020年7月21日)
CoppeliaSim V4.0.0(2019年11月26日)
…
…
CoppeliaSim是机器人仿真器里的“瑞士军刀”:你不会发现一个比它拥有更多功能,特色甚至更详尽的应用编程接口的机器人仿真器:
机器人、机器人学、仿真器、仿真、运动学、动力学、路径规划、最短距离计算、碰撞检测、视觉传感器、图像处理、接近传感器、油漆分散仿真。
CoppeliaSim应用程序由几个元素组成。它的主要元素是:
以下是CoppeliaSim应用程序的典型视图:
当您启动CoppeliaSim应用程序时,CoppeliaSim将初始化一个默认场景。用户可以自由地并行打开多个场景。每个场景与其他场景共享应用程序窗口和对话框,但是在应用程序窗口或对话框中只有活动的场景内容可见(在给定时间仅一个场景可见)。
在下一节中,将简要介绍应用程序窗口的元素。有关对话框的详细信息,请参阅本参考手册中的相关页面。
CoppeliaSim中的页面是场景的主要查看界面。它不是直接的视图,而是可以根据需要包含一个、两个或任意多个视图。视图是用来显示必须是可见对象的特定对象的图像内容的视图。例如,如果视图与相机对象相关联,则它可以显示相机看到的内容。下图说明了页面,视图和可见对象的关系:
视图在页面内可以具有固定位置,也可以在页面上具有浮动位置。以下页面配置说明了页面上方,视图和可见对象之间的关系:
CoppeliaSim中的每个场景都有八个可自由配置的页面。可以通过页面选择器工具栏按钮访问(即显示)各个页面:
创建新场景时,将以不同方式预配置8个页面中的每个页面。可以使用[弹出菜单->删除页面]来删除页面。页面不存在(即已删除的页面)显示暗灰色的表面。然后可以使用[弹出菜单->使用…设置页面]创建页面和具有空视图的默认页面配置。可以使用几种页面配置,如下图所示(数字表示视图索引):
以上页面配置允许显示1-8个固定视图。浅灰色表面中的每一个对应一个空视图(即未关联的视图)。任何时候都可以使用[弹出菜单->删除页面]来删除页面。删除页面还将删除其包含的所有视图,但不会删除任何关联的对象。在现有页面配置之上,可以使用[弹出菜单->添加->浮动视图]添加无限数量的浮动视图。下图显示了这样一个示例:
浮动视图可以移动和调整大小,但不允许使用鼠标左键或右键进行导航(例如,摄像机平移、摄像机旋转等)。双击一个浮动视图以将其内容与视图索引0交换(但是可以通过编程禁用它来禁止此操作)。要删除浮动视图,只需单击其右上角的按钮。
要将可查看对象与视图关联,请选择该对象,然后在要与之关联的视图上单击[弹出菜单->视图->将视图与所选摄像机关联]或[弹出菜单->视图->将视图与选定的视觉传感器关联](弹出菜单将根据最后选定的对象自动调整其内容)。创建视图但尚未与可见对象关联时,[弹出菜单->添加->摄像机]命令将添加摄像机并将其直接与视图关联(即浏览)。给定的可见对象可以同时与任意数量的视图关联。
或者,您还可以通过激活视图中的以下弹出窗口将视图与可见对象相关联:[弹出菜单->视图->视图选择器…]。这将打开视图选择器。
将查看对象与视图关联后,将显示其图像内容,但视觉传感器的操作方式除外:视觉传感器需要生成其图像内容,并且只有在调用适当的API命令时才会发生。默认情况下,主脚本包含一个将处理场景中所有视觉传感器的命令(sim.handleVisionSensor(sim.handle_all))。除非将视觉传感器标记为显式处理而不是explicitely handled,否则它将在模拟过程中生成其图像内容。
可以通过以下方式自定义或调整与相机关联的视图:
Federico Ferri提供的自定义UI插件(simExtCustomUI)提供了基于Qt框架的功能。 该插件的源代码可以在这里找到。
自定义UI插件提供Qt样式的小部件,例如集成按钮、编辑框、滑块、标签、图像等的对话框。对自定义UI的任何操作(例如,按钮单击、文本编辑、滑块移动)都报告为脚本回调 。 其他功能可通过相关的API函数调用来访问。 这样可以在很大程度上自定义仿真。 以下显示了一个典型的自定义UI:
用户可以使用以下工具栏按钮之一来修改和操纵对象或项目的位置和方向 :
第一个显示位置对话框,第二个显示方向对话框。 在这两种情况下,用户都将能够使用鼠标移动选定的对象或项目。
当选择对象转换工具栏按钮时,位置对话框变为可见:
该对话框具有四个不同的选项卡:
鼠标移动
在对话框的此部分中,可以设置用鼠标操作的对象的移动参数。另请参见有关通过鼠标移动对象的页面。
在对话框的此部分中,可以实现精确的对象或项目移动。
在对话框的此部分中,可以实现对象或项目位置的精确缩放。
选择对象旋转工具栏按钮时,方向对话框将可见:
该对话框具有三个不同的选项卡:
鼠标旋转
在对话框的此部分中,可以设置用鼠标操作的对象的旋转参数。另请参见有关通过鼠标移动对象的页面。
除了通过坐标和变换对话框修改对象配置之外,还可以使用鼠标直接操作对象:选择对象(和某些项目)后,可以使用以下工具栏按钮来平移或旋转对象:
默认情况下,平移是在世界的X-Y平面上执行的。对于每个对象,还可以沿着不同的轴/平面并且相对于不同的参考系执行此操作,具体取决于位置对话框中的设置。青色覆盖图表示当前平移平面或轴。
默认情况下,绕对象自己的Z轴执行旋转。对于单个对象,还可以围绕不同的轴或相对于不同的参考系执行该操作,具体取决于方向对话框中的设置。青色叠加图表示当前的旋转轴。
可以在用户设置对话框中调整默认的平移和旋转步长(捕捉),但是建议分别保持5厘米和5度的值,或者分别设置对象的步长。在对象操作过程中按下鼠标按钮后,按住Shift键可以暂时禁用捕捉。以类似的方式,在对象操作过程中按下鼠标按钮后,按住ctrl键可以临时激活其他平移或旋转轴。
当模拟器处于顶点编辑模式或路径编辑模式时,也可以使用对象/项目转换工具栏按钮。
欧拉角是描述刚体方向的三个角度。 谈论欧拉角时有十二种不同的约定。 在CoppeliaSim中,欧拉角 α \alpha α、 β \beta β和 γ \gamma γ(或(a,b,g))描述了由三个基本旋转组成的旋转:
其中Rx,Ry和Rz分别代表绝对参考系围绕x、y和z轴的元素旋转。
对于刚体或场景对象,如果按照以下顺序围绕其自身的参考系旋转,则可以获得相同的变换:围绕自身X旋转 α \alpha α,然后围绕自身Y旋转 β \beta β,接着围绕自身Z旋转 γ \gamma γ。
CoppeliaSim中的某些值和设置不依赖于场景或模型,而是依赖于用户。 可以使用[菜单栏->工具->设置]或单击以下工具栏按钮来访问用户设置对话框(部分反映了system/usrset.txt的内容):
当焦点位于场景层次结构或页面上时,支持以下快捷键:
1)普通
,2)对象平移
和 3)对象旋转
鼠标模式之间切换通过命令行启动CoppeliaSim时,支持以下命令行选项:
例如,要以无头模式启动CoppeliaSim,加载场景myScene.ttt,运行模拟5秒钟,然后停止模拟并自动再次离开CoppeliaSim,从CoppeliaSim主文件夹中键入:
Windows:coppeliaSim.exe -h -s5000 -q myScene.ttt
Mac:./ coppeliaSim.app/Contents/MacOS/coppeliaSim -h -s5000 -q ../../../myScene.ttt
Linux:./ coppeliaSim.sh -h -s5000 -q myScene.ttt
场景和模型是CoppeliaSim的主要模拟元素。模型是场景的子元素,明确标记为模型。场景可以包含任何数量的模型。下图说明了场景模型关系:
场景和模型都可能包含以下元素中的一个或多个:
除上述元素外,场景还将包含以下元素:
场景保存在*.ttt
文件中,模型保存在*.ttm
文件中。这两种文件类型都可以通过从资源管理器窗口中将它们拖放到CoppeliaSim应用程序来打开。也可以双击打开它们。
与模型相比,场景可以包含完全相同类型的元素,但还包括特定于场景的以下元素:
场景或场景图像内容可以通过一个与视图相关联的可视对象查看,视图本身包含在一个页面中。当创建一个新的场景时([菜单栏->文件->新场景]),默认的场景将包含以下元素:
可以使用[菜单栏->文件->打开场景…]打开(加载)场景,并使用[菜单栏->文件->保存场景]或[菜单栏->文件->保存场景为…]保存场景。场景文件("*.ttt"-files)也支持在资源管理器窗口和应用程序窗口之间的拖放操作。也可以双击场景文件,在这种情况下,它们将启动CoppeliaSim应用程序并打开。
只需在场景层次结构的上部单击即可切换已打开的场景(所有打开的场景都在场景层次结构的顶部分组),或者通过相关工具栏按钮使用场景选择器来实现:
模型是场景的子元素。除了文件(“ * .ttm”-文件类型)外,模型本身不能存在,也不能通过自身进行模拟。模型必须包含在场景中才能运行。
通过在同一层次树上构建的场景对象的选择来定义模型,其中树的基础必须是标记为对象是模型基础的对象。可以通过[菜单栏->文件->加载模型…]来加载它们。但是,通过在模型浏览器和场景视图之间进行拖放操作来加载模型更加容易和方便。可以使用[菜单栏->文件->将模型另存为…]保存模型,只需确保选择了一个标记为对象为模型库的单个对象,否则将模型另存为…-菜单项未启用。还请确保遵循有关如何构建清晰仿真模型的教程。
通过以下步骤定义模型:
现在,无法再在场景中选择建立在模型基础上的单个对象(选择它们将改为选择模型的基础),但是仍然可以通过在选择过程中按住Ctrl和Shift键来单独选择它们,或者通过在场景层次中选择它们。除此之外,当选择基础对象时,将显示一个包围整个模型的点画边界框,如下图所示:
注意标记为模型基础的对象图标左侧的模型标签:
双击模型标签可打开模型对话框,可在其中调整模型属性。修改模型的层次结构后,最好折叠模型的层次结构,以便轻松识别逻辑分组的元素/模型的数量:
当子脚本以编程方式访问对象时,将多个对象分组为模型也很重要。请记住,在CoppeliaSim中,对象/模型可以随时复制,甚至在模拟过程中也可以复制。为了使复制的子脚本能够访问正确的对象(不是原始对象,而是复制的对象),应始终在访问子脚本的同时复制子脚本。保证的一种方法是创建模型(如上所述),并确保访问模型中对象的子脚本与模型中包含的对象相关联。最好的方法是将一个子脚本(也可能有第二个子脚本)与模型的基础关联。有关更多信息,请参考以编程方式访问对象部分。
为了使模型易于组合(即彼此构建)而无需进行任何其他修改,重要的是要考虑模型将扮演什么角色;会动态模拟吗?它会被附加到其他型号,还是会接受其他附加模型?这些问题的答案将使您能够选择最佳对象类型作为模型基础。有关更多信息,请参考设计动态仿真部分。
复制和粘贴模型的行为与保存模型然后加载(就像使用内存缓冲区而不是磁盘空间一样)完全相同。可以将模型从一个场景复制到另一个场景,就像其他对象一样。模型文件(“ * .ttm”文件)还支持资源管理器窗口和应用程序窗口之间的拖放操作。也可以双击模型文件,在这种情况下,它们将启动CoppeliaSim应用程序并加载到默认场景中。
可以在模型对话框中单独调整模型的属性。
可以在模型对话框中单独调整模型的属性。可以双击场景层次中的模型图标来打开它:
CoppeliaSim中的环境定义了属于场景但不属于场景对象的属性和参数。 保存模型时不保存环境属性和参数,而仅在保存场景时保存。
环境定义以下属性和参数:
可以通过[菜单栏->工具->环境]或通过双击场景层次结构中的以下图标来访问环境对话框:
纹理对话框允许您查看和修改与附加到形状的纹理相关的属性。 通过在形状属性对话框中单击“设置纹理项目”可以访问它:
纹理是可以应用于曲面以使其看起来更真实的位图图像。 想象一下,在矩形表面上应用砖纹理以使其看起来像砖墙。 下图说明了带纹理的表面:
CoppeliaSim将纹理应用于形状的默认方式是将其投影到形状的x / y平面上,如下图所示:
支持以下5种纹理映射方法:
建议保持默认设置,以保持与旧显卡的高兼容性(选中“将纹理缩放至”时,无论如何将所有纹理的大小调整为2的幂),并且文件大小应较小。
一旦纹理存储在内存中,就可以在实际映射发生之前对其进行缩放,移动和旋转,以获得所需的视觉外观。
可以通过单击“加载新纹理”按钮来加载静态纹理。 当前支持以下文件格式:
除了从文件中加载纹理,您还可以选择已加载的静态纹理,甚至是视觉传感器生成的动态纹理。 只需单击“从现有纹理中选择纹理”按钮。 请注意,动态纹理仅在模拟过程中才能正确显示(并且只有在正确处理了相关视觉传感器的情况下才可以显示)。
实体是指场景对象或集合的术语。 下图说明了场景对象、集合、实体之间的关系:
CoppeliaSim中用于构建模拟场景的主要元素是场景对象(简称为对象)。 对象在场景层次结构和场景视图中可见。 在场景视图中,对象具有三维表示,如下图所示:
下面简要介绍了每种对象类型的功能:
以上某些对象可以具有特殊的属性,从而允许其他对象或计算模块与它们进行交互。 对象可以是:
每个对象在模拟场景中都有一个位置和方向。 我们将物体的位置和方向称为物体的构型。 对象可以附加到其他对象(或在彼此的顶部构建)。 如果对象A构建在对象B之上,则对象B是父对象,而对象A是子对象。 要在对象B和对象A之间创建父子关系,请选择对象A,然后选择对象B(选择顺序很重要)。 然后选择[菜单栏–>编辑–>使最后选择的对象为父对象]。 下图说明了此操作:
或者,可以将一个对象拖放到场景层次中的另一个对象上,以获得类似的结果。 请注意,对象A的配置没有更改(两个对象都保留了各自的配置)。 但是,查看场景层次结构,您可以看到对象A成为对象B的子对象。如果现在移动对象B,对象A将自动跟随,因为对象A附加到对象B。通过选择对象A,然后选择[菜单栏–>编辑–>使所选对象孤立],可以分离对象A。 这样做将在不更改其配置的情况下分离对象A。 或者,您可以将对象拖放到世界图标上以获得类似的结果。
每个对象都具有相对于世界参考系的绝对配置(或累积配置)和相对于父对象参考系的本地配置(或相对配置)。 在上面的示例中,当对象A成为对象B的子级时,对象A的绝对配置没有改变,但是它的本地配置被修改了。
最后选定对象的绝对配置显示在信息文本中。 要修改或调整对象的绝对或局部配置,请参考坐标和变换对话框以及有关对象位置/方向操纵的部分。
一些对象数据可以由图形对象记录。 有关如何记录对象数据的详细信息,请参阅图形和图形数据流。
场景对象属性对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
场景对象属性对话框显示与对象(即场景对象)相关的属性。 该对话框是上下文相关的,其内容将主要取决于场景对象选择状态:仅显示最后选择的对象的属性。 这些属性分为两个部分:
对话框上部的2个按钮允许选择要显示的所需属性类型。 如果对象选择为空,则所有对话框项目都将处于非活动状态。
对话框的对象类型特定属性部分将显示以下对话框之一,具体取决于最后选择的对象的类型:
对象通用属性对话框是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击通用按钮以显示对象通用属性对话框。 该对话框显示最后一个选定对象的设置和参数。 如果未选择任何对象,则该对话框处于非活动状态。 如果选择了多个对象,则可以将一些参数从最后一个选择的对象复制到其他选择的对象(应用于选择-按钮):
缩放:在CoppeliaSim中可以灵活地缩放对象或模型。 对象或模型的大小以及所有相关属性都会适当缩放(例如,关节范围、速度设置、质量等)。 以便缩放的对象或模型可以正常继续操作(但比例不同)。
装配:打开一个对话框,该对话框允许指定装配工具栏按钮在装配过程中如何处理对象(如果对象的装配方式与通过装配工具栏按钮不同,则以下设置不会有任何影响):
对象选择顺序对于装配操作很重要,即首先选择要成为子对象的对象,然后选择要成为父对象的对象。 如果选择顺序错误,或者成为父对象不合适,那么如果没有歧义,CoppeliaSim将尝试猜测用户的真实意图(例如,通过在成为父对象的后代中搜索合适的匹配)。
可碰撞物体是可以测试与其他可碰撞物体碰撞的物体,即将记录碰撞状态的物体。 这并不意味着它们会对碰撞做出响应(即可响应),这是不同的。 可碰撞对象包括:
由于基于点,因此虚拟对象和点云只能与OC树(基于体积)发生碰撞。
集合也是可碰撞的,因为它们可能包含可碰撞的对象。
可碰撞对象可以单独启用或禁用其可碰撞属性(默认情况下为非纯图形、OC树和点云启用)。 这可以在对象通用属性中设置,也可以通过sim.setObjectSpecialProperty API函数设置。
此外,根据可碰撞对象的相关模型特性(如果它们是模型的一部分),可碰撞对象的可碰撞特性可以被替代。 有关详细信息,请参考模型对话框。
可测量对象是可用于相对于其他可测量对象进行最小距离计算的对象。 它们包括:
集合也是可度量的,因为它们可能包含可度量的对象。
可以单独启用或禁用可测量对象的可测量特性(默认情况下为非纯形状、OC树和点云启用)。 这可以在对象通用属性中设置,也可以通过sim.setObjectSpecialProperty API函数设置。
此外,根据可测量对象的相关模型特性(如果它们是模型的一部分),可测量对象的可测量特性可以被替代。 有关详细信息,请参考模型对话框。
可检测对象是可由接近传感器检测到的对象。 它们包括:
由于以点为基础,射线类型或随机化类型的接近传感器不能检测到虚拟对象和点云。
所有接近传感器都可以检测到可检测的对象,或者只能通过特定类型的接近传感器,或者说列出的一个子类别的接近传感器可以检测到可检测的对象:
集合也是可检测的,因为它们可能包含可检测的对象。
可检测对象可以单独启用或禁用其可检测属性,这适用于所有类型的接近传感器(默认情况下为非纯形状启用)。 这可以在对象通用属性中设置,也可以通过sim.setObjectSpecialProperty API函数设置。
此外,根据可检测对象的相关模型属性(如果它们是模型的一部分),可以覆盖它们的可检测属性。 有关详细信息,请参考模型对话框。
可渲染对象是视觉传感器可以看到或检测到的对象。 它们包括:
集合也是可渲染的,因为它们可能包含可渲染对象。
您可以使可渲染对象仅由特定视觉传感器看到。 可渲染对象还可以单独启用或禁用其可渲染属性(默认情况下启用,纯形状除外)。 这可以在对象通用属性中设置,也可以通过sim.setObjectSpecialProperty API函数设置。
此外,根据可渲染对象的相关模型属性(如果它们是模型的一部分),可以覆盖可渲染对象的可渲染属性。 有关详细信息,请参考模型对话框。
可查看对象是可以透视、查看或可以显示某些图像内容的对象。 它们包括:
可查看对象可以与将显示其图像内容的视图相关联。
CoppeliaSim允许计算和添加指定对象的凸壳。 网格集合的凸壳是包含所有网格的最小凸壳。 CoppeliaSim只允许提取可测量对象的凸壳。 计算出的凸面外壳可能不是“水密的”(即可能包含重叠的三角形或非共享边),因此该形状不会被标记为凸面。 但是,您可以对生成的形状运行凸分解函数。
要添加凸面外壳,请选择要包含在凸面外壳中的对象,然后选择[菜单栏–>添加–>凸面外壳选择]([Menu bar–>Add–>Convex Hull of Selection])。
根据情况的不同,凸壳可以大大减少计算时间,例如,在距离计算或接近传感器模拟的情况下。 如果改为使用复杂形状的更粗糙近似(即凸壳),也可以更快地执行碰撞检测。 还可以提取模型(例如机器人)的凸壳,然后使其不可见,但执行所有计算(碰撞检测、距离计算等)。 用不可见的凸包代替复杂的模型。
对象选择对话框是根据对象类型选择对象的便捷方法,无需浏览场景层次。 在形状编辑模式或路径编辑模式下,该对话框还可用于反转项目选择。 可通过[菜单栏–>工具–>选择]或点击以下工具栏按钮进入:
图层选择对话框是显示或隐藏场景特定部分的便捷方式。 可以将每个场景对象指定给16个可用可见性图层中的任何一个(请参阅对象通用属性)。 使用此对话框可以单独激活/取消激活每个层。 如果某些对象应该是不可见的,请尝试将它们隐藏在未激活的图层中(例如,当前图层+8)。 保存场景时,始终尝试保持默认激活状态(前8层全部启用,后8层禁用)。 其原因是,如果将模型从场景复制并粘贴到另一个场景中,则某些本应不可见的对象可能会突然变得可见。 在模拟期间,该对话框提供了仅显示场景的动态内容(仅可视化动态内容)的可能性,这通常有助于调试目的。
图层选择对话框可通过[Menu Bar–>Tools–>Layers]或点击以下工具栏按钮访问:
相机是可查看的对象,这意味着您可以通过它们查看并显示它们正在查看的内容的视图。 您可以在场景中根据需要拥有任意多个摄影机,每个摄影机都提供不同的场景视图。 下面显示了一个包含多个摄影机的场景示例:
一定不要把相机和视觉传感器弄混了。 以下是主要区别:
可以通过[菜单栏–>添加–>摄像机]将摄像机添加到场景中。 但是,以这种方式添加相机会将对象添加到默认位置和方向。 更好的做法是在场景的特定视图上单击鼠标右键并选择[弹出菜单–>添加–>摄像机]来添加摄像机。 这会将对象添加到当前视图的正前方。 系统会自动选择添加的摄像机,然后您可以通过[弹出菜单–>视图–>将视图与所选摄像机关联]进行查看。 要使其正常工作,您必须确保在视图上激活了弹出菜单。 当视图创建完成但尚未关联可见对象时,[弹出式菜单–>添加–>摄像机]命令会添加一个摄像机,并将其与视图直接关联(即浏览)。 相机可以与任意数量的视图相关联。
或者,您也可以通过在视图中激活以下弹出窗口将视图与摄像机关联:[弹出菜单–>视图–>视图选择器…]。 这将允许您从预览窗口中选择所需的相机视图。 当相机与视图相关联时,可以使用鼠标通过以下工具栏按钮对其进行操作:
虽然鼠标左键允许上述操作,但鼠标滚轮允许沿视图方向移动相机(如果相机视图处于透视投影模式)或允许调整相机视图的视图大小(如果相机视图处于正交投影模式)。 当在没有鼠标移动的情况下点击右键时,将激活弹出菜单,但是,如果在移动鼠标的同时保持按住右键,则可以实现围绕所点击的点的相机旋转。
激活相机Shift按钮后,可以非常轻松地在场景中导航到任何所需的位置和方向,方法是:(1)使用鼠标左键垂直于视图方向移动,(2)使用鼠标滚轮沿视图方向移动,以及(3)使用鼠标右键绕单击点旋转:(1)鼠标左键用于垂直于查看方向移动,(2)用于沿查看方向移动的鼠标滚轮,以及(3)用于围绕单击点旋转的鼠标右键:
通过选择要跟踪的对象,然后在适当的视图中选择[弹出式菜单–>视图–>跟踪选定的对象],摄像机可以自动跟踪对象(即,在对象移动时跟踪对象)。 跟踪相机将保持其位置不变,但会自动调整其观察方向,以便始终将要跟踪的对象保持在其视场中。 这不同于通过父子关系将摄影机附加到该对象。
摄像机属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击摄影机按钮以显示摄影机对话框(仅当最后选择的是摄影机时才会显示摄影机按钮)。 该对话框显示上次选择的摄像机的设置和参数。 如果选择了多个摄像机,则可以将一些参数从上次选择的摄像机复制到其他选定的摄像机(应用于选择-按钮):
灯光是允许您照亮场景的对象。 在场景中没有任何灯光的情况下,对象以未明暗处理的颜色显示(在这种情况下,对象仅使用可以在环境对话框中设置的环境光组件照明)。 下图说明了场景中灯光的效果:
一个场景中最多可以有八个活动灯光。 有三种不同类型的灯光:
可以使用[菜单栏–>添加–>灯光]将灯光添加到场景中。
灯光属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击灯光按钮以显示灯光对话框(仅当最后选择的是灯光时才会显示灯光按钮)。 该对话框显示上次选择的灯光的设置和参数。 如果选择了多个灯光,则可以将一些参数从上一个选定灯光复制到其他选定灯光(应用于选择按钮):
形状是由三角面组成的刚性网格对象。 它们可以导入、导出和编辑。 它们有四种不同的子类型:
默认情况下,所有导入的形状都是简单形状。 但是,可以对两个或多个简单形状或复合形状进行分组([菜单栏–>编辑–>分组/合并–>分组/合并–>分组选定的形状])或取消分组([菜单栏–>编辑–>分组/合并–>取消分组选定的形状])。 也可以合并简单的形状([菜单栏–>编辑–>分组/合并–>合并选定的形状],在这种情况下,所有组成元素的可视属性都相同。 形状也可以划分([菜单栏–>编辑–>分组/合并–>分割选定的形状]),具体取决于其配置:划分算法将提取形状的每个不同元素。 如果两个元素没有任何共同点,那么它们就是截然不同的。 另请参阅模型教程。 它说明了如何正确导入和准备仿真模型的形状。
纯形状主要是功能性形状。 大多数情况下,它们仅由物理引擎使用,物理引擎在它们上的性能比在非纯图形(例如随机或凸面网格)上的性能要好得多,速度也快得多。 因此,纯形状通常隐藏在不可见的层中(例如,层9)。 有关详细信息,请参阅层选择对话框和有关如何设计动态模拟的部分。
纯简单形状也可以分组,但是,只有当其所有组成元素也都是纯的时,得到的复合形状才是纯的。 合并纯简单形状将产生非纯简单形状。
形状是可碰撞、可测量、可检测和可渲染的对象。 这意味着形状:
可以在对象通用属性中改变形状的可碰撞、可测量、可检测和可渲染属性。 此外,如果形状是替代这些特性的模型的一部分,则可以替代这些特性。 有关详细信息,请参考模型对话框。
可在CoppeliaSim中使用的形状计算(即碰撞、距离和接近传感器计算)也可通过Coppelia几何例程作为独立例程使用。
形状和每个对象一样,都有一个参考框和一个边界框。 参考框架或坐标框架始终位于形状的几何中心,并指示计算形状位置和方向的点。 坐标框架有三个轴:x轴、y轴和z轴,分别对应于红色、绿色和蓝色箭头。 形状的边界框围绕形状的参考框架居中,方向与参考框架相同(x轴、y轴和z轴与边界框的边缘具有相同的方向)。 边界框完全包围形状。 用户可以从4种不同的方式中选择来定义形状的参考框和边界框方向(纯简单形状和Heightfield形状不能重定向):
也可以在几何体对话框中或通过API修改边界框相对于其形状的方向。
除了从外部文件导入形状之外,还可以通过选择[Menu bar–>Add–>Primitive Shape]在CoppeliaSim内直接创建形状。 支持以下5个基本体形状:
可以在基本体形状对话框中调整基本体形状的几何参数:
(*)细分和面属性不能直接显示且没有直接效果。 下面显示了两个具有不同细分参数的相似形状:
细分数较高的形状以更具差异性的方式反射照明。 有关详细信息,请参见三角形编辑模式和细分最大三角形选项。
应在形状属性中调整颜色和其他视觉属性。 也可以在形状编辑模式或几何图形对话框中调整和编辑形状网格。
导入形状
CoppeliaSim使用三角形网格来描述和显示形状。 因此,CoppeliaSim将仅导入将对象描述为三角形网格的格式。 但是,如果您希望导入描述为参数曲面的对象(例如IGES等),则必须首先将文件转换为适当的三角网格格式。 有几个转换应用程序允许此操作,并且大多数3D绘图应用程序也非常好地支持此操作。 请确保您更深入地阅读这些部分,以便能够获得适用于您的3D图形的最佳三角网格描述。
CoppeliaSim支持以下用于形状导入的文件格式([Menu Bar–>File–>Import–>Mesh…]):
导入功能由CoppeliaSim的Assimp插件处理。 有关其API函数,请参阅此处。 如果使用所需的标志重新编译Assimp库(和Assimp插件),则可以支持更多格式。
如果在导入操作之后,您在场景中看不到任何形状,但场景层次指示存在新添加的形状,则很可能是您的形状太大或太小而看不见。 然后,您可以继续在对象通用属性中执行缩放操作。 此外,当从CAD应用程序导出网格时,请尝试将它们作为一个整体导出(最好是将它们作为单个对象导出,稍后在CoppeliaSim中,您可以使用[Menu Bar–>Edit–>Grouping/Merging–>Divide Selected Shares]分割导入的形状);这是为了避免CAD应用程序在导出操作期间根据各个网格的参考帧重新定位/重定向各个网格(CoppeliaSim的参考帧不同!),这可能会导致外观损坏。
确保导入的网格不包含太多三角形(对于机器人,通常总共包含10000-20000个三角形),否则CoppeliaSim可能会显著减慢(渲染、计算、加载/保存操作等)。 有些应用程序允许减少网格中的多边形数(例如,MeshLab或多边形crunsher)。 您还可以使用以下CoppeliaSim函数:
从将形状作为参数曲面处理的应用程序(例如IGES等)中导出形状时,当绘图由大对象和小对象组成时,分几个步骤导出对象可能很重要;这是为了避免大对象定义得太精确(三角形太多)和小对象定义太粗糙(三角形太小);只需先导出大对象(通过调整所需的精度设置),然后导出小对象(通过向上调整精度设置)。
还要确保遵循有关如何构建干净的仿真模型的教程。
导出形状
CoppeliaSim支持以下文件格式进行形状导出[菜单栏–>文件–>导出–>所选形状…] (注意:将仅导出选定的对象):
导出功能也由CoppeliaSim的Assimp插件处理。 有关其API函数,请参阅此处。
导入高度场
CoppeliaSim支持以下文件格式用于高度域形状导入([Menu Bar–>File–>Import–>Heightfield…]):
选择要导入的文件后,将打开一个对话框:
CoppeliaSim允许计算和添加指定形状的凸分解。在动态碰撞响应计算方面,凸形比随机形状执行得更快、更稳定。 然而,它们不像纯形状那样快,也不像纯形状那样稳定!
可以添加选定形状的凸分解,也可以将选定形状变形为其等效的凸分解:
将弹出以下对话框,并允许调整形状的分解方式:
以下参数适用于每个单独的形状:
形状属性是场景对象属性对话框的一部分,该对话框位于[菜单栏->工具->场景对象属性]。 可以通过双击场景层次结构中的对象图标或单击其工具栏按钮来打开对话框:
在场景对象属性对话框中,单击图形按钮以显示图形对话框(仅当最后选择的是图形时,才会显示图形按钮)。 该对话框显示上次选定图形的设置和参数。 如果选择了多个形状,则可以将一些参数从上次选择的形状复制到其他选择的形状(应用于选择-按钮):
上面的某些参数仅适用于简单形状。 选择复合形状后,可以通过切换到复合形状的形状编辑模式来编辑其视觉属性。 当然,您也可以将其取消分组,以便单独编辑其组件。
形状动力学对话框是形状属性的一部分。 该对话框显示上一个选定图形的动力学设置和参数。 如果未选择任何对象,则该对话框处于非活动状态。 如果选择了多个形状,则可以将一些参数从上次选择的形状复制到其他选择的形状(应用于选择-按钮):
物体是可响应的:如果启用,则该形状将与其他可响应形状产生碰撞反应,但仅当各自的可响应遮罩重叠时才会产生碰撞反应(请参见下面的项目)。 有关详细信息,请参见设计运动仿真部分。
可响应掩码:指示何时生成冲突响应(但在可响应项目上方需要启用)。 掩码由本地和全局两个8位值组成。 如果两个碰撞形状共享其任何父图形(直接或间接),则使用局部遮罩,否则使用全局遮罩。 如果两个形状的AND组合遮罩(局部或全局)不同于零,则将生成冲突响应。
编辑材料:允许编辑所有动力学引擎的材料属性,如摩擦、恢复等。
物体是动态的:启用后,图形的位置和方向将在动力学模拟中受到影响。 有关详细信息,请参见设计运动仿真部分。
在休眠模式下启动:动态模拟的可响应形状可以在休眠模式下启动,在这种情况下,除非它首先与另一个可响应形状碰撞,否则它不会对约束(例如重力)做出反应。
如果获取父对象,则设置为动态:如果启用此选项,并且该形状附加到另一个对象,则该形状将自动设置为动态形状。 这对于模型基座非常有用,这些模型基座在单独运行时应该是静态的,但在与其他模型/对象组合时是动态的(例如,单独操作的机器人机械手通常将其基座设置为静态,但当连接到车辆时,该基座应变为动态)。
计算选定形状的质量和惯性属性:通过单击此按钮,可以基于材料均匀密度自动计算选定凸形的质量和惯性属性。
质量:形状的质量。 使用M=M*2(用于选择)和M=M/2(用于选择)按钮,选定形状的质量可以轻松增加或减少系数2。这便于通过试错法快速找到稳定的仿真参数。
主惯性矩/质量:无质量(即除以形状的质量)的主惯性矩。 使用i=i*2(用于选择)和i=i/2(用于选择)按钮,选定形状的无质量惯性值可以轻松增加或减少系数2。 这便于通过试错法快速找到稳定的仿真参数。
位置/方向。 相对于形状坐标系的惯性坐标系&COM:相对于形状参照系表示的惯性坐标系和质心的配置。
相对于绝对坐标系设置惯性矩阵(&COM):打开惯性矩阵对话框,允许指定相对于绝对参考系的惯性属性:
材料属性(即与形状相关的动力学引擎属性)可以通过形状动态属性对话框访问。 上一个选定造型的材质属性将显示在一个对话框中:
Bullet属性
与Bullet物理库相关的属性。 有关详细信息,请参考Bullet用户手册。
ODE属性
与ODE相关的属性。 有关详细信息,请参考ODE用户手册。
Vortex属性
与Vortex Studio引擎相关的属性。 请参考Vortex用户手册了解详细信息。
Newton属性
与牛顿动力学引擎相关的属性。 有关详细信息,请参考牛顿用户手册。
Votex附加信息
材质属性定义单个形状在与另一个形状碰撞时的行为方式。 碰撞涉及两个形状及其各自的材质属性。 接触材料将这两种材料特性组合成一组合并的特性,用于在仿真执行期间生成两个碰撞形状之间的接触力。 合并两种触头材料的规则如下:
如果摩擦不是各向同性的,则可以在定义摩擦面(线性主轴和次轴)的两个方向上提供不同的摩擦特性。 轴方向是对象的局部框架中的向量。 它在摩擦面上的投影定义了线性主方向。 轴方向仅用于各向异性材质。 如果两种各向异性材料相互作用,则将使用其中一种材料,用户当前无法确定哪种材料的优先级。
形状几何图形对话框是形状属性的一部分。 该对话框允许查看与形状关联的几何图形,并在一定程度上对其进行修改。 它显示顶点和三角形的数量,以及形状边界框的大小。 网格的顶点和三角形的数量与渲染和计算时间直接相关(例如,在碰撞检测或距离计算期间),网格的顶点/三角形越多,模拟或场景显示就越慢。 虽然对象通用属性允许缩放对象(包括形状),但它始终保持相同的比例(沿对象的x轴、y轴或z轴的缩放是相同的)。 此限制不适用于几何体对话框,您甚至可以通过指定负比例因子来沿网格的一个轴翻转网格。 但是,请记住,一些纯简单形状和纯复合形状对非均匀缩放有限制。 最重要的是,纯形状不能翻转。
此外,使用形状几何图形对话框可以修改形状的边界框方向。 这应该只在非常特殊的情况下使用。 修改形状边框方向的首选方法是在选中形状时选择[菜单栏–>编辑–>边界框对齐–>将所选形状的坐标框与主轴对齐]或[菜单栏–>编辑–>边界框对齐–>与世界对齐所选形状的坐标框]。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W9dr8mdX-1602468809257)(Selection_783.png)]
当CoppeliaSim中需要特定形状时,最佳选择是在CAD应用程序(例如AutoCAD、3D Studio Max等)中绘制它们。 然后再导入它们。 当外部CAD应用程序不可用或仅需要简单形状时,用户可以创建基本体形状,然后在CoppeliaSim中支持的3种形状编辑模式之一自定义创建的形状:
在进入上述编辑模式之一之前,纯形状将转换为规则形状。
复合形状不能直接编辑。 首先必须将其解组。 也可以通过复合形状的编辑模式编辑其组成元素的视觉参数。
单击相应的工具栏按钮即可访问不同的编辑模式:
确保在进入形状编辑模式之前选择了形状对象。 在形状编辑期间,不能选择对象,也不能启动模拟。 编辑完成后,单击形状编辑模式工具栏按钮即可进入编辑模式。 将更改应用于形状时,CoppeliaSim将确保修改后的形状是一致的,并移除不使用的顶点并合并彼此接近的顶点等。具体行为可以在用户设置对话框中的顶点/三角形验证设置中设置。
您可以从一种编辑模式切换到另一种模式,这允许您实现特殊操作。 例如,如果要选择并移除圆柱体上表面的所有三角形,而不是在三角形编辑模式下单独选择它们,请在顶点编辑模式下按住Shift并选择所有上部顶点,然后切换到三角形编辑模式,然后按Delete键。
单击相应的工具栏按钮即可进入三角形编辑模式:
以上工具栏按钮仅在选定形状时才处于活动状态。 如果最后选择的形状不是简单形状,而是复合形状,则将改为激活复合形状的编辑模式。 在三角形编辑模式中,单独显示组成形状的所有三角形。 三角形有两个面,正面和背面。 正面显示为蓝色,背面显示为红色。 选择三角形时(使用与选择对象相同的步骤),它们将显示为黄色,而最后选择的三角形将显示为白色。 支持快捷复制/剪切/粘贴/删除(ctrl-c、ctrl-x、ctrl-v、delete)。 可以使用Esc-键、使用取消选择工具栏按钮或通过按住Ctrl并单击场景的空白区域来清除选择。 按住Shift键选择将选择选择区域下的所有三角形,也会选择隐藏的三角形(如果您希望通过按住Shift键只选择可见的三角形,请在按住Shift键的同时按住Ctrl键)。 在三角形编辑模式中,窗口中通常显示场景层次的部分用于将正在编辑的形状的三角形显示为列表。 与层次窗口中的对象一样,可以使用鼠标选择列表中的项目。
进入三角形编辑模式后,编辑菜单项([菜单栏–>编辑])将变为专用于三角形编辑模式,并显示如下对话框:
可以使用鼠标直接平移三角形,使用工具栏的对象/项目平移按钮将垂直平面中的选定三角形平移到视图方向:
通过单击相应的工具栏按钮可以访问顶点编辑模式:
以上工具栏按钮仅在选定形状时才处于活动状态。 如果最后选择的形状不是简单形状,而是复合形状,则将改为激活复合形状的编辑模式。 在顶点编辑模式中,组成图形的所有顶点将分别显示为红色。 选择顶点时(使用与选择对象相同的步骤),它们将显示为黄色,最后选择的顶点显示为白色。 支持快捷复制/剪切/粘贴/删除(ctrl-c、ctrl-x、ctrl-v、delete)。 可以使用Esc-键、使用取消选择工具栏按钮或通过按住Ctrl并单击场景的空白区域来清除选择。 按住Shift键选择将选择选择区域下的所有顶点,也会选择隐藏顶点(如果希望通过按住Shift键只选择可见顶点,请在按住Shift键的同时按住Ctrl键)。 在顶点编辑模式中,窗口中通常显示场景层次的部分用于将正在编辑的图形的顶点显示为列表。 与层次窗口中的对象一样,可以使用鼠标选择列表中的项目。
进入顶点编辑模式后,编辑菜单项([Menu Bar–>Edit])将变为特定于顶点编辑模式,并显示如下对话框:
可以通过坐标和变换对话框精确定位顶点。 也可以使用鼠标直接平移它们,使用工具栏的对象/项目平移按钮将垂直平面中的选定顶点/顶点平移到视图方向:
单击相应的工具栏按钮即可访问边编辑模式:
以上工具栏按钮仅在选定形状时才处于活动状态。 如果最后选择的形状不是简单形状,而是复合形状,则将改为激活复合形状的编辑模式。 在边编辑模式中,组成形状的所有边分别显示为红色。 选择边时(使用与选择对象相同的步骤),它们将显示为黄色,而最后选择的边将显示为白色。 可以使用DELETE键删除边,但不能复制、剪切或粘贴边。 可以使用Esc-键、使用取消选择工具栏按钮或通过按住Ctrl并单击场景的空白区域来清除选择。 按住Shift键选择将选择选择区域下的所有边,也会选择隐藏边(如果希望通过按住Shift键选择仅选择可见边,请在按住Shift键的同时按住Ctrl键)。 在边编辑模式中,窗口中通常显示场景层次的部分用于将正在编辑的形状的边显示为列表。 与层次窗口中的对象一样,可以使用鼠标选择列表中的项目。
进入边缘编辑模式后,编辑菜单项([Menu Bar–>Edit])将变为特定于边缘编辑模式,并将显示以下对话框:
可以使用鼠标直接平移边,使用工具栏的对象/项目平移按钮将垂直平面中的选定边平移到视图方向:
通过单击相应的工具栏按钮可以访问复合形状的编辑模式:
以上工具栏按钮仅在选定形状时才处于活动状态。 如果最后选择的形状不是复合形状,而是简单形状,则将改为激活三角形编辑模式。 在复合形状的编辑模式中,可以编辑形状的各个组件的各个可视参数。 可以在层次窗口中选择形状的组件。
进入复合形状编辑模式后,将显示如下对话框:
关节是至少具有一个固有自由度(DoF)的对象。 关节用于构建机构和移动对象,如下图所示:
使用[菜单栏–>添加–>关节]将关节添加到场景中。 请参考模型创建教程中的运动类型部分。 某些关节数据可以由图形对象记录。 有关如何记录接头数据的详细信息,请参阅图形和图形数据流。
与另一个对象相比,一个关节有两个参考帧(仅当选择该关节时可见)。 第一个是固定的常规参照系,其他物体也有。 第二个参考系不是固定的,将根据定义其配置的运动类型位置(或运动类型值)相对于第一个参考系移动。
关节类型
支持4种类型的关节:
关节用于允许其父对象和子对象之间的相对运动。 在关节和对象之间建立父子关系时,对象将附加到关节的第二个参考系,因此,关节配置(固有位置)的更改将直接反映到其子对象上。 可以使用[菜单栏–>添加–>关节]将新关节添加到场景中。
关节类型
关节可以处于以下模式之一:
当关节处于被动模式、反向运动学模式或从属模式时,也可以选择以混合方式操作;混合操作允许关节以常规方式操作,但另外,就在动力学计算之前,当前关节位置将被复制到目标关节位置,然后在动力学计算期间,关节将作为位置控制中的马达进行处理(如果且仅当其处于动态启用状态时(有关详细信息,请参阅设计动力学模拟一节))。 例如,该特征允许通过简单地指定所需的脚位置(作为反向运动学任务)来控制类人机器人的腿;然后,相应的计算出的关节位置将被应用为腿动态运动的位置控制值。
关节控制器
有许多不同的方法可以控制关节。 在接下来的部分中,我们将区分松散控制器和精确控制器:松散连接控制器将不能在每个可能的调节步骤中提供新的控制值(例如,可能/将跳过一些调节步骤,但仍然可以控制)。 另一方面,精确的关节控制器将能够在每个可能的调节步骤中提供控制值。
首先,控制关节的方法将取决于关节模式:
区别来自于这样一个事实,即在力/扭矩模式下操作的关节将由物理引擎处理。 并且默认情况下,物理引擎将执行比模拟循环多10倍的计算步骤;模拟循环以20 Hz(在模拟时间)运行,而物理引擎以200 Hz(也是在模拟时间)运行。 如果需要,可以完全配置该默认行为。
如果关节不处于力/扭矩模式:如果关节不处于力/扭矩模式,则可以通过sim.setJointPosition API函数(或类似函数,例如,用于基于B0的远程API的simxSetJointPosition或用于传统远程API的simxSetJointPosition)直接(即时)设置其位置。 您可以从子脚本、插件、ROS节点、BlueZero节点或远程API客户端执行此操作。 如果从子脚本执行此操作,则应在非线程化子脚本的激活部分内完成,或从在主脚本的感测阶段之前执行的线程化子脚本执行(默认)。 但是,在后一种情况下,请确保线程化的子脚本与模拟循环同步,以便进行精确控制。
在下面的线程子脚本示例中,关节的位置控制松散,并且与模拟循环没有同步:
-- Following script should run threaded:
jointHandle=sim.getObjectHandle('Revolute_joint')
sim.setJointPosition(jointHandle,90*math.pi/180) -- set the position to 90 degrees
sim.wait(2) -- wait 2 seconds (in simulation time)
sim.setJointPosition(jointHandle,180*math.pi/180) -- set the position to 180 degrees
sim.wait(1) -- wait 1 second (in simulation time)
sim.setJointPosition(jointHandle,0*math.pi/180) -- set the position to 0 degrees
etc.
在下面的线程化子脚本示例中,在每个模拟步骤中精确控制关节的位置,即线程与模拟循环同步:
-- Following script should run threaded:
sim.setThreadSwitchTiming(200) -- Automatic thread switching to a large value (200ms)
jointHandle=sim.getObjectHandle('Revolute_joint')
sim.setJointPosition(jointHandle,90*math.pi/180) -- set the position to 90 degrees
sim.switchThread() -- the thread resumes in next simulation step (i.e. when t becomes t+dt)
sim.setJointPosition(jointHandle,180*math.pi/180) -- set the position to 180 degrees
sim.switchThread() -- the thread resumes in next simulation step
sim.setJointPosition(jointHandle,0*math.pi/180) -- set the position to 0 degrees
sim.switchThread() -- the thread resumes in next simulation step
-- etc.
-- In above code, a new joint position is applied in each simulation step
当您尝试从外部应用程序(例如,通过远程API、ROS或BlueZero)控制非力/扭矩模式的关节时,外部控制器将异步运行到CoppeliaSim(即,类似于线程化子脚本的非同步代码)。 对于松散控制,这在大多数情况下都很好,但如果您希望在每个模拟循环中精确控制关节的位置,则必须在同步模式下运行CoppeliaSim,并且外部控制器(例如远程API客户端)必须明确触发每个模拟步骤。
下面说明了执行此操作的基于C++ B0的远程API客户端:
bool doNextStep=false;
void simulationStepDone_CB(std::vector<msgpack::object>* msg)
{
doNextStep=true;
}
int main(int argc,char* argv[])
{
...
client.simxSynchronous(true); // enable the synchronous mode
client.simxGetSimulationStepDone(client.simxDefaultSubscriber(simulationStepDone_CB)); // callback when step finished
client.simxStartSimulation(client.simxDefaultPublisher()); // start the simulation
client.simxSetJointPosition(jointHandle,90.0f*3.1415f/180.0f,client.simxDefaultPublisher()); // set the joint to 90 degrees
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
client.simxSetJointPosition(jointHandle,180.0f*3.1415f/180.0f,client.simxDefaultPublisher()); // set the joint to 180 degrees
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
client.simxSetJointPosition(jointHandle,0.0f*3.1415f/180.0f,client.simxDefaultPublisher()); // set the joint to 0 degrees
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
...
}
有关基于B0的远程API同步模式如何准确运行的详细信息,请参阅本页。 该方法与ROS或BlueZero类似。
不过,对于旧式远程API客户端,下面也会执行相同的操作:
...
simxSynchronous(clientId,1); // enable the synchronous mode (client side). The server side (i.e. CoppeliaSim) also needs to be enabled.
simxStartSimulation(clientId,simx_opmode_oneshot); // start the simulation
simxSetJointPosition(clientId,jointHandle,90.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint to 90 degrees
simxSynchronousTrigger(clientId); // trigger next simulation step. Above commands will be applied
simxSetJointPosition(clientId,jointHandle,180.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint to 180 degrees
simxSynchronousTrigger(clientId); // next simulation step executes. Above commands will be applied
simxSetJointPosition(clientId,jointHandle,0.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint to 0 degrees
...
有关传统远程API同步模式如何准确运行的详细信息,请参阅此页。 该方法与ROS或BlueZero类似。
如果关节处于力/扭矩模式:如果关节在力/扭矩模式下运行并且处于动态启用状态,则它将由物理引擎间接处理。 如果您的关节的马达未启用,则您的关节不受控制(即它将是自由的)。 否则,您的关节可以处于以下两种动态模式:
关节的马达处于启用状态,但控制回路处于禁用状态。 当您希望从外部应用程序(例如,力/扭矩控制、PID等)精确自定义控制关节时,请使用此模式。 当您想要在力/力矩模式下松散地控制关节,或用于速度控制(例如机器人车轮马达)时,也可以使用此模式。
关节的马达处于启用状态,控制回路也处于启用状态。 当关节需要充当弹簧/阻尼器时,或者如果要从CoppeliaSim内精确自定义控制关节,或者希望从外部应用程序松散地控制关节的位置控制,请使用此模式。
如果启用了关节的马达,但禁用了控制回路,则物理引擎将应用指定的最大力/扭矩,并加速关节,直到达到目标速度。 如果载荷较小和/或最大力/扭矩较高,将很快达到目标速度。 否则,这将需要一些时间,或者,如果力/扭矩不够大,将永远达不到目标速度。 可以使用sim.setJointTargetVelocity以编程方式调整目标速度(例如,对于基于B0的远程API:simxSetJointTargetVelocity,或者对于传统远程API:simxSetJointTargetVelocity),以及使用sim.setJointForce调整最大力/扭矩(例如,对于基于B0的远程API:simxSetJointForce,或者对于传统远程API:simxSetJointForce)。 在从子脚本为处于力/转矩模式的关节编写精确的关节控制器之前,应非常小心,原因如下:
默认情况下,模拟循环以50ms的时间步长运行(在模拟时间中)。 但物理引擎将以5ms的时间步长运行,即频率增加10倍。 将在每个模拟步骤中调用子脚本,但不会在每个物理引擎计算步骤中调用子脚本。 这意味着,如果您以常规方式从子脚本控制关节,您将只能为10个物理引擎计算步骤提供一次新控制值:您将缺少9个步骤。 克服此问题的一种方法是更改默认模拟设置,并将模拟时间步长指定为5ms,而不是50ms。 这可以很好地工作,但请记住所有其他计算(例如,视觉传感器、接近传感器、距离计算、IK等)。 还将运行10倍以上的频率,并最终降低模拟速度(大多数情况下,其他计算模块不需要如此高的刷新率。 但是物理引擎需要如此高的刷新率)。 另一个更好的选择是使用联合回调函数(或动态回调函数),下面将对此进行说明。
另一方面,如果您想要在外部(例如,从远程API客户端、ROS节点或BlueZero节点)运行精确而常规的关节控制器,那么您别无选择,只能将模拟环路设置为与物理引擎速率相同的速率,然后以同步模式运行CoppeliaSim,并且外部控制器(例如,远程API客户端)将必须明确地触发每个模拟步骤。
下面说明了执行此操作的基于C++B0的远程API客户端:
bool doNextStep=false;
void simulationStepDone_CB(std::vector<msgpack::object>* msg)
{
doNextStep=true;
}
int main(int argc,char* argv[])
{
...
client.simxSynchronous(true); // enable the synchronous mode
client.simxGetSimulationStepDone(client.simxDefaultSubscriber(simulationStepDone_CB)); // callback when step finished
client.simxStartSimulation(client.simxDefaultPublisher()); // start the simulation
// set the desired force and target velocity:
client.simxSetJointForce(jointHandle,1.0f,client.simxDefaultPublisher());
client.simxSetJointTargetVelocity(jointHandle,180.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
// set the desired force and target velocity:
client.simxSetJointForce(jointHandle,0.5f,client.simxDefaultPublisher());
client.simxSetJointTargetVelocity(jointHandle,180.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
// set the desired force and target velocity:
client.simxSetJointForce(jointHandle,2.0f,client.simxDefaultPublisher());
client.simxSetJointTargetVelocity(jointHandle,180.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
...
}
有关基于B0的远程API同步模式如何准确运行的详细信息,请参阅本页。 该方法与ROS或BlueZero类似。
不过,对于旧式远程API客户端,下面也会执行相同的操作:
...
simxSynchronous(clientId,1); -- enable the synchronous mode (client side). The server side (i.e. CoppeliaSim) also needs to be enabled.
simxStartSimulation(clientId,simx_opmode_oneshot); // start the simulation
simxSetJointForce(clientId,jointHandle,1.0f,simx_opmode_oneshot); // set the joint force/torque
simxSetJointTargetVelocity(clientId,jointHandle,180.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint target velocity
simxSynchronousTrigger(clientId); // trigger next simulation step. Above commands will be applied
simxSetJointForce(clientId,jointHandle,0.5f,simx_opmode_oneshot); // set the joint force/torque
simxSetJointTargetVelocity(clientId,jointHandle,180.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint target velocity
simxSynchronousTrigger(clientId); // next simulation step executes. Above commands will be applied
simxSetJointForce(clientId,jointHandle,2.0f,simx_opmode_oneshot); // set the joint force/torque
simxSetJointTargetVelocity(clientId,jointHandle,180.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the joint target velocity
...
有关传统远程API同步模式如何准确运行的详细信息,请参阅此页。 该方法与ROS或BlueZero类似。
如果启用了关节的马达,并且也启用了控制回路,则物理引擎将根据设置处理关节:您的关节可以在位置控制(即PID控制)、弹簧/阻尼器模式或自定义控制下运行。 PID和弹簧/阻尼器参数可以从子脚本、远程API客户端、ROS或BlueZero节点更新。 参见对象参数ID 2002-2004、2018-2019年。 可以使用sim.setJointTargetPosition(或者,例如,从基于B0的远程API客户端:simxSetJointTargetPosition,或者从传统的远程API客户端:simxSetJointTargetPosition)设置所需的目标位置。 如果需要精确的自定义控制器,则应改用关节回调函数(或动力学回调函数)。
最后,如果您需要在外部应用程序中实现的精确PID或自定义控制器,则需要确保模拟步骤与物理引擎计算步骤相同:默认情况下,CoppeliaSim的模拟循环运行频率为20 Hz(在模拟时间内),而物理引擎运行频率为200 Hz。 可以在仿真设置中调整仿真步长。 您还需要确保在同步模式下运行CoppeliaSim。
下面说明了执行此操作的基于C++B0的远程API客户端:
bool doNextStep=false;
void simulationStepDone_CB(std::vector<msgpack::object>* msg)
{
doNextStep=true;
}
int main(int argc,char* argv[])
{
...
client.simxSynchronous(true); // enable the synchronous mode
client.simxGetSimulationStepDone(client.simxDefaultSubscriber(simulationStepDone_CB)); // callback when step finished
client.simxStartSimulation(client.simxDefaultPublisher()); // start the simulation
// set the desired target position:
client.simxSetJointTargetPosition(jointHandle,90.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
// set the desired target position:
client.simxSetJointTargetPosition(jointHandle,180.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
doNextStep=false;
// set the desired target position:
client.simxSetJointTargetPosition(jointHandle,0.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
...
}
不过,对于旧式远程API客户端,下面也会执行相同的操作:
...
simxSynchronous(clientId,1); -- enable the synchronous mode (client side). The server side (i.e. CoppeliaSim) also needs to be enabled.
simxStartSimulation(clientId,simx_opmode_oneshot); // start the simulation
simxSetJointTargetPosition(clientId,jointHandle,90.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the desired joint position
simxSynchronousTrigger(clientId); // trigger next simulation step. Above commands will be applied
simxSetJointTargetPosition(clientId,jointHandle,180.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the desired joint position
simxSynchronousTrigger(clientId); // next simulation step executes. Above commands will be applied
simxSetJointTargetPosition(clientId,jointHandle,0.0f*3.1415f/180.0f,simx_opmode_oneshot); // set the desired joint position
...
您还可以让远程API客户端通过向关节回调函数提供值(例如通过信号)来为在关节回调函数中实现的自定义关节控制器提供控制值。 例如,从基于C++B0的远程API客户端:
bool doNextStep=false;
void simulationStepDone_CB(std::vector<msgpack::object>* msg)
{
doNextStep=true;
}
int main(int argc,char* argv[])
{
...
client.simxSynchronous(true); // enable the synchronous mode
client.simxGetSimulationStepDone(client.simxDefaultSubscriber(simulationStepDone_CB)); // callback when step finished
client.simxStartSimulation(client.simxDefaultPublisher()); // start the simulation
// set the desired target position:
simxSetFloatSignal("myDesiredTorque",1.0f,client.simxDefaultPublisher());
simxSetFloatSignal("myDesiredTarget",90.0f*3.1415f/180.0f,client.simxDefaultPublisher());
client.simxSynchronousTrigger(); // start one simulation step
while (!doNextStep) // wait until simulation step finished
client.simxSpinOnce();
...
}
在上面的示例中,您的联合回调函数可以在执行控制之前获取这两个信号(使用sim.getDoubleSignal)。
不过,对于旧式远程API客户端,下面也会执行相同的操作:
...
simxSynchronous(clientId,1); -- enable the synchronous mode (client side). The server side (i.e. CoppeliaSim) also needs to be enabled.
simxStartSimulation(clientId,simx_opmode_oneshot); // start the simulation
simxSetFloatSignal(clientId,"myDesiredTorque",1.0f,simx_opmode_oneshot); // set the signal value
simxSetFloatSignal(clientId,"myDesiredTarget",90.0f*3.1415/180.0f,simx_opmode_oneshot); // set the signal value
simxSynchronousTrigger(clientId); // trigger next simulation step. Above commands will be applied
...
关节属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击关节按钮以显示关节对话框(仅当最后选择的是关节时,才会显示关节按钮)。 该对话框显示上次选定关节的设置和参数。 如果选择了多个关节,则可以将某些参数从上一个选定关节复制到其他选定关节(应用于选择按钮。 请注意,这仅在相同类型或模式的关节之间有效):
运动类型动力学特性是运动类型特性的一部分。 其对话框显示上次选定关节的动力学设置和参数。 如果未选择任何对象,则该对话框处于非活动状态。 如果选择了多个关节,则可以将某些参数从上一个选定关节复制到其他选定关节(应用于选择按钮。 请注意,这仅在相同类型或模式的关节之间有效):
可以通过关节动力学属性对话框访问与关节相关的动力学引擎属性。 对话框中将显示上一个选定运动类型的引擎特定特性。 如果选择了多个关节,则可以将属性从最后一个选定关节复制到其他选定关节(将所有属性应用于选定关节):
Bullet属性
与Bullet物理库相关的属性。 有关详细信息,请参考Bullet用户手册。
ODE属性
与Open Dynamics引擎相关的属性。 有关详细信息,请参考ODE用户手册。
Vortex属性
与Vortex Studio引擎相关的属性。 请确保还参考Vortex用户手册了解详细信息。
Newton属性
与牛顿动力学引擎相关的属性。 有关详细信息,请确保还参考牛顿用户手册。
虚拟对象是可用的最简单的对象:它是一个有方向的点,可以将其视为参考系。 单独使用它们没有多大用处,但是当与其他对象或计算模块一起使用时,它们可能非常重要,虚拟对象是多用途或辅助对象。 下图显示了一个虚拟对象:
虚拟对象是可碰撞、可测量和可检测的物体。 这意味着虚拟对象:
默认情况下,虚拟对象的可碰撞、可测量和可检测属性处于禁用状态(请参见对象通用属性)。
可以使用[Menu bar–>Add–>Dummy]将虚拟对象添加到场景中,或在顶点编辑模式下从形状对象创建虚拟对象。
虚拟对象是多用途对象。 它们可以具有非常特定的功能,也可以仅用作辅助对象。 以下是常见的虚拟功能:
虚拟属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击虚拟按钮以显示虚拟对话框(仅当最后一个选择是虚拟时才会显示虚拟按钮)。 该对话框显示上次选择的虚拟对象的设置和参数。 如果选择了多个虚拟对象,则可以将一些参数从上次选择的虚拟对象复制到其他选定的虚拟对象(应用于选择按钮):
图表是可用于记录、可视化或从仿真导出数据的对象。 他们非常强大和灵活。 用户可以从应用于特定对象的多种数据类型中选择要记录的数据类型。 数据记录为数据流(数据值的顺序列表),可以通过三种不同的方式进行可视化:
下图说明了图形功能:
使用[Menu Bar–>Add–>Graph]将图形添加到场景中。 你看到的是图形的三维表示。 如果为该图形定义了3D曲线,则该曲线直接可见,如下图所示:
图表记录的数据流可以导出到*.csv文件(逗号分隔值),该文件可以由各种应用程序(如Excel)轻松导入。 在场景中,选择要从中导出数据的图形,然后选择[Menu Bar–>File–>Export–>Selected Graphs as CSV…]。 导出的数据流的单位将是米、公斤、秒和度(或它们的组合)。
图表属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击图形按钮以显示图形对话框(仅当最后选择的是图形时,才会显示图形按钮)。 该对话框显示上次选择的图形的设置和参数。 如果选择了多个图形,则可以将一些参数从上次选择的图形复制到其他选择的图形(应用于选择-按钮):
XY图形和3D曲线对话框是图形属性的一部分。 该对话框显示与上次选择的图形对象的XY图形或3D曲线相关的设置和参数。
添加新曲线:允许添加新的XY图形或3D曲线项目。 新项目将显示在对话框的列表中,并且可以编辑其名称。 单击添加新曲线按钮将打开以下对话框:
曲线可见:确定选定曲线是否可见。
链接点:确定选定曲线的单个(x,y)或(x,y,z)值是否将与直线链接。
显示标签:确定选定曲线的标签是否可见。
调整颜色:允许调整所选曲线的颜色。
复制到静态:选择曲线后,单击此按钮将把该曲线复制为静态曲线。 启动新仿真时,静态流或静态曲线(显示为点划线)不会被修改或清除,它们用于将一个仿真运行的结果与另一个仿真运行的结果进行比较。 数据流或曲线也可以通过在图形视图(浮动视图除外)中选择数据流或曲线,然后单击[弹出菜单–>添加–>曲线的静态复制]来设置为静态。 可以使用图形属性对话框中的删除所有静态流/曲线按钮清除静态流或曲线。
曲线始终在顶部:确定选定曲线是否始终可见,即使被其他对象隐藏。 此属性仅适用于3D曲线。
相对于图形:如果选中此选项,则所选曲线将相对于图形对象的参考帧显示。 此属性仅适用于3D曲线。
相对于世界:如果选中此选项,则所选曲线将相对于绝对参考坐标系显示。 此属性仅适用于3D曲线。
曲线宽度:选定曲线的宽度。 此属性仅适用于3D曲线。
CoppeliaSim提供了一种非常强大和高效的方式来模拟接近传感器。 用户可以模拟几乎任何类型的接近传感器,从超声波到红外线等等。 允许此功能的场景对象是可以检测可检测实体的接近传感器(与视觉传感器不同)。 下图说明了使用接近传感器的模拟:
使用[菜单栏–>添加–>接近传感器]将接近传感器添加到场景中。
接近传感器使用的接近传感器检测例程也可以通过Coppelia几何例程作为独立例程使用。
接近传感器有6种不同类型,可在很大程度上进行定制:
接近传感器以几何上精确的方式运行:它们在其感应点(小球体)和干扰其检测体积的任何可检测实体之间执行精确的距离计算(它们不像大多数其他模拟软件那样在传感体积边缘之间执行简单的碰撞检测,而是在检测体积内执行精确的距离计算)。 每个接近传感器将计算以下最小距离:
如果接近传感器检测到对象,则激活触发器,这将导致调用触发器回调函数。
接近传感器的计算结果可以通过图形对象记录下来。 有关如何记录接近传感器数据的更多信息,请参阅图形和图形数据流类型。
接近传感器属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击接近感应器按钮以显示接近感应器对话框(仅当最后选择的是接近感应器时,才会显示接近感应器按钮)。 该对话框显示上次选择的接近传感器的设置和参数。 如果选择了多个接近传感器,则可以将一些参数从最后选择的接近传感器复制到其他选择的接近传感器(应用于选择按钮):
接近传感器体积对话框是接近传感器属性的一部分。 该对话框显示上次选择的接近传感器的音量设置和参数。 如果未选择任何对象,则该对话框处于非活动状态。 如果选择了多个接近传感器,则可以将一些参数从最后选择的接近传感器复制到其他选择的接近传感器(应用于选择按钮):
面数、面数Far、细分和细分Far可以或多或少地精确地描述检测体。 更高的精度也意味着更长的计算时间。
内部间隙:该参数仅适用于圆盘型和圆锥型接近传感器。 它的值可以在0到1之间变化,表示要移除的体积(按比例)。 此功能可用于通过组合多个传感器来创建非常复杂的检测体:
接近传感器检测参数对话框是接近传感器属性的一部分。 该对话框显示上次选择的接近传感器的各种检测参数。
除了接近传感器,CoppeliaSim还提供了另一种传感器:视觉传感器。 视觉传感器是可查看的对象,其操作方式与相机对象非常相似,它们将渲染其视野中的对象,并在指定的阈值过高或过低时触发检测。 可以检测可渲染实体的视觉传感器应主要在颜色、光或结构在检测过程中起作用时(例如,红外传感器,或更一般地,对光敏感的传感器(相机等)),而不是接近传感器。 但是,根据应用程序在其上运行的显卡或场景对象的复杂程度,视觉传感器可能比接近传感器慢一点。 下面说明了使用视觉传感器的应用:
一定不要把视觉传感器和摄像机弄混了。 以下是主要区别:
视觉传感器通过[菜单栏–>添加–>视觉传感器]添加到场景中。
视觉传感器有两种不同的类型,可以针对不同的目的进行调整:
视觉传感器是可查看的对象,可以像摄像机对象一样透视[弹出式菜单–>视图–>将视图与选定的视觉传感器关联]。 有关更多详细信息,另请参阅页面和视图部分。
视觉传感器非常强大,因为它们可以以各种灵活的方式使用。 例如,它们可以用来显示来自外部应用程序或插件的静止或运动图像。 插件还可以提供定制的图像处理算法以及评估算法(例如触发条件)。 视觉回调函数表示可以进行图像处理和生成触发器的机制(可以对触发器回调函数中的触发器做出反应)。
视觉传感器只能渲染(和检测)可渲染实体。
视觉传感器属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击视觉传感器按钮以显示视觉传感器对话框(仅当最后选择的是视觉传感器时,才会显示视觉传感器按钮)。 该对话框显示上次选择的视觉传感器的设置和参数。 如果选择了多个视觉传感器,则可以将一些参数从最后选择的视觉传感器复制到其他选择的视觉传感器(应用于选择按钮):
力传感器最初是两个形状之间的刚性连接,能够测量传递的力和扭矩。 力传感器的刚度是有条件的,因为如果出现特定条件(例如,如果力或扭矩阈值超标),力传感器可能会损坏。 下图说明了使用力传感器的应用程序:
力传感器测量一对表示传感器沿x、y和z轴的力以及传感器围绕x、y和z轴的扭矩的3个值:
最初,力传感器充当刚性连杆。 但是,在仿真过程中,当指定力/扭矩阈值过高或满足某些其他用户定义的条件时,力传感器可能会损坏。 下图说明了力传感器的损坏状态:
力传感器只有在动态启用的情况下才能在模拟期间运行。 有关动态启用力传感器的详细信息,请参阅设计动态模拟一节。 运动类型也能够测量力或扭矩,但是只能沿/围绕其z轴。
力传感器通过[菜单栏–>添加–>力传感器]添加到场景中。
力传感器属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击力传感器按钮以显示力传感器对话框(仅当最后选择的是力传感器时,才会显示力传感器按钮)。 该对话框显示上次选定力传感器的设置和参数。 如果选择了多个力传感器,则可以将一些参数从上一个选定力传感器复制到其他选定力传感器(应用于选择按钮):
路径是在空间中定义路径或轨迹的对象。 它可以用于各种任务,如下图所示:
路径对象可以通过[菜单栏–>添加–>路径]添加到场景中。 默认情况下有两个基本路径可用:简单线段类型路径或圆形类型路径。 它们可以定向或缩放,但通常这是不够的。 用户有几种可选方案来生成自定义路径对象:
路径本身并不能起到多大作用。 它们通常与假人和其他对象一起使用,以获得所需的效果。 要沿路径移动对象,首先需要为该路径指定一个虚拟对象,然后可以将该对象附加到将跟随该路径的固有运动的虚拟对象。 有关更多详细信息,请参阅有关虚拟对象的部分。
路径是可渲染的对象,这意味着视觉传感器可以看到路径。 但是,需要启用路径整形功能。 可以在对象公共属性中更改路径的可呈现属性。
一些路径数据可以由图形对象记录。 有关如何记录路径数据的详细信息,请参阅图形和图形数据流类型。
路径具有位置和方向组件(或通道),并且还可以另外具有描述速度剖面的组件。 路径由控制点定义,这些控制点将路径描述为一系列链接的线段。 仅当选择路径时,控制点才可见:
路径的第一个控制点(起点)表示为球体,其余控制点表示为立方体。 路径可以是开放的,也可以是闭合的。 当它关闭时,它会变成循环的。
每个控制点都具有可以围绕其附近更详细地描述路径的属性:每个控制点可以描述是否以及如何计算Bezier曲线。 下面说明了此属性:
默认情况下,Bezier点始终可见(未选择对象时也是如此),并显示为指示Bezier点(实际上是具有方向的点)的x轴、y轴和z轴的红绿蓝小箭头。 贝塞尔曲线部分由3个参数描述,如下图所示:
Bezier插值因子指示Bezier曲线部分的开始和结束位置,Bezier点计数指示曲线的详细程度(或平滑程度)。 从技术上讲,Bezier点数为1将禁用Bezier曲线插值机制,但为简单起见,控制点随后称为Bezier点。
可以在路径编辑模式中手动调整控制点的位置和方向。 但是,不能单独调整Bezier点方向。 它相当于自动计算出来的。 默认情况下,Bezier点的方向将遵循路径曲率(如果启用了自动方向选项),否则将使用控制点的方向进行插值,如下图所示:
沿着路径对象,可以定义固有位置。 该位置也称为路径位置,不同于路径对象的位置。 虽然路径对象的位置是路径对象原点的位置(在选择路径时显示为白色线框立方体),但是路径位置或更确切地说,内在路径位置是沿路径的位置值,如下图所示:
路径的Bezier点可以是不同的或重合的:设想一个焊接机器人,其末端执行器是焊接设备的尖端;在两个连续的Bezier点之间,末端执行器可以:
此外,在某些情况下,我们希望焊枪遵循预定义的路径,在某个特定位置暂停(例如处理较大的焊点),然后沿着路径继续。 为了正确处理上述3种情况和特殊的暂停情况,重要的是能够唯一地标识沿路径的任何位置*(广义的位置)(即路径位置*),以及路径长度*(广义的长度)。 为此,用户可以在几种位置计算方法中进行选择:
其中, Δ l \Delta l Δl和$ \Delta \alpha$分别是两个连续贝塞尔点之间的线性变化和角度变化。 角度**变化是规则的角度变化乘以角度系数C。C称为角度到线性的转换系数,它允许将角度值与线性值组合在一起。 这意味着位置*沿路径或路径长度*总是以线性单位(例如米)给出,而与上面选择的位置计算方法无关。
默认情况下,用红色标记的术语为零。 该术语可以被视为贝塞尔(Bezier)点(或路径控制点)的虚拟距离或第四坐标(即,每个贝塞尔点随后将由方向和位置(x,y,z,w)定义,其中w是第四坐标)。 这对于存档路径上的暂停点非常有用。 是两个连续Bezier点之间的虚拟距离变化。 D是虚拟距离变化的比例因子(例如,如果d加倍,则所有暂停点将执行两倍长的暂停持续时间)。 为简化起见,在下面的内容中我们将不再提及此术语,并假定它为零。
以下示例阐明了位置和长度计算的概念:
要将路径上特定点的移动暂停存档,请执行以下操作:创建3个完全相同的路径控制点(位置和方向完全重合),并为中间控制点指定不同于零的虚拟距离值。 在以下示例中,3个重合点处的虚拟距离为2(第一个重合控制点和中间重合控制点之间的虚拟距离为1,中间重合控制点和第三个重合控制点之间的虚拟距离为1)。 如果对象以每秒1米的速度沿路径移动,则它将在重合控制点存档2秒的暂停:
应根据应用情况仔细选择路径位置/长度计算方法。
当前固有路径位置在路径上显示为红色球体(如果启用了路径位置显示)。 在使用sim.setPathPosition进行模拟期间,可以随时控制球体沿路径的位置。 确保您了解路径位置或路径长度是如何计算的。
要实际使对象沿路径移动,首先需要将对象附加到虚拟对象,然后指定虚拟对象跟随路径位置(具有可选偏移)。 有关更多详细信息,请参阅有关虚拟对象的部分。
或者,可以使用sim.postPath或sim.getPositionOnPath、sim.setObjectPosition、sim.getOrientationOnPath和sim.setObjectOrientation命令使对象跟随路径。
路径是一个纯功能对象,没有任何花哨的视觉属性。 然而,有时人们想要显示更精细的轨迹(例如隧道、铁轨等)。 或者从路径生成网格(即形状)。 为此,模拟器提供路径整形功能,可以在路径属性的路径整形部分启用或禁用该功能。 路径成形的工作原理是将截面轮廓放置在路径上的不同位置,如下图所示:
路径整形参数可通过单击显示路径整形对话框按钮进行调整:
路径属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击路径按钮以显示路径对话框(仅当最后选择的是路径时,才会显示路径按钮)。 该对话框显示上次选择的路径的设置和参数。 如果选择了多条路径,则可以将一些参数从上次选择的路径复制到其他选择的路径(应用于选择-按钮):
路径导入/导出功能对CSV文件(逗号分隔值)进行操作,这些文件可以使用简单的文本编辑器创建或读取,但也可以轻松导入/导出到Microsoft Excel等应用程序中。
导入路径
CoppeliaSim的导入功能([Menu Bar–>File–>Import–>Path from CSV…])逐行读取值,其中每行对应一个控制点。 每行应按以下方式格式化:
x,y,z,alpha,beta,gamma,relativeVelocity,BezierPointCount,interpolationFactor1,interpolationFactor2,
virtualDistance,auxiliaryFlags,auxiliaryChannel1,auxiliaryChannel2,auxiliaryChannel3,auxiliaryChannel4
在:
除前3个值(控制点位置坐标)外,所有其他值都可以省略,在这种情况下将应用默认值。
导出路径
通过选择路径,然后单击[菜单栏–>文件–>导出–>所选路径为CSV…],可以导出路径的控制点。 这种情况下的导出格式与前面描述的路径导入格式相同。
路径的Bezier点也可以通过点击路径,然后点击[Menu Bar–>File–>Export–>Selected Path‘s Bezier Curve as CSV…]导出。 在这种情况下,创建的文件(导出的文件)中的每一行都对应于一个贝塞尔点,并包含下列值:
x,y,z,alpha,beta,gamma,relativeVelocity,virtualDistance,auxiliaryFlags,auxiliaryChannel1,auxiliaryChannel2,
auxiliaryChannel3,auxiliaryChannel4
初步说明:路径编辑模式是编辑路径对象的一种方便且功能齐全的方式。 但是,可以移动和删除单个路径点,而无需进入路径编辑模式以进行最小限度的路径修改(选择单个路径点时,请确保未选择路径以外的任何其他对象)。
单击相应的工具栏按钮即可访问路径编辑模式:
仅当选择路径时,上述工具栏按钮才处于活动状态。 在路径编辑模式下,窗口中通常显示场景层次的部分用于将路径控制点显示为列表。 与层次窗口中的对象一样,可以使用鼠标选择列表中的项目。
现在可以像选择常规对象一样选择各个控制点。 上次选定的控制点显示为白色,其他选定的控制点显示为黄色,未选定的控制点显示为蓝色。 以类似的方式,可以使用鼠标直接平移控制点,使用工具栏的对象/项目平移工具栏按钮将垂直平面中的选定控制点平移到视图方向:
在路径编辑模式下,将显示路径编辑模式对话框:
要精确定位控制点,请使用坐标和变换对话框。 如果要编辑控制点的方向,请确保禁用路径的自动方向选项(默认情况下启用该选项)。
常规组合键(即ctrl-c、ctrl-v、delete和ctrl-x)支持复制/粘贴/删除/剪切操作。 确保主视图具有焦点,以便按键生效。 如果未选择控制点,粘贴操作会将复制的控制点粘贴到控制点列表的开头,否则将粘贴在所选控制点之后(请确保在此阶段选择的控制点不超过一个)。 也可以通过弹出菜单或通过[主菜单–>编辑]访问相同的复制/粘贴/删除/剪切功能。 其他操作包括:
在路径开始处插入新路径点/选择后插入新路径点:如果没有选择控制点,则在路径开始处插入新控制点,否则在当前选择之后插入新控制点(在这种情况下,请确保选择的控制点不超过一个)。
从Bezier曲线生成新路径:使用当前路径的Bezier点生成新的路径对象,即新路径的控制点将是当前路径的Bezier点。
OC树是表示空间分区的对象。 它由树数据结构组成,其中每个节点正好有八个子节点。 占用的叶节点被表示为体素。 OC树可用于提供形状或点云的简化表示,或可用作占用网格/空间:
OC树是可碰撞、可测量和可检测的对象。 这意味着OC树:
OC树可以通过[菜单栏–>添加–>OC树]添加到场景中,并通过OC树属性进行编辑。
CoppeliaSim中提供的OC树计算(即碰撞、距离和接近传感器计算)也可通过Coppelia几何例程作为独立例程提供。
OC树属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击OC树按钮以显示OC树对话框(仅当最后选择为OC树时,才会显示OC树按钮)。 该对话框显示上次选择的OC树的设置和参数:
点云是充当基于OC树的点容器的对象:
点云是可碰撞、可测量和可检测的对象。 这意味着点云:
点云可以通过[菜单栏–>添加–>点云]添加到场景中,并通过点云属性进行编辑。
CoppeliaSim中提供的点云计算(即碰撞、距离和接近传感器计算)也可通过Coppelia几何例程作为独立例程提供。
点云属性是场景对象属性对话框的一部分,该对话框位于[菜单栏–>工具–>场景对象属性]。 也可以通过双击场景层次中的对象图标或单击其工具栏按钮来打开该对话框:
在场景对象属性对话框中,单击点云按钮以显示OC树对话框(仅当最后选择的是点云时,才会显示点云按钮)。 该对话框显示上次选定的点云的设置和参数:
集合是用户定义的场景对象集合。 集合必须至少包含一个对象,并且被视为实体(对象也是实体)。 例如,当引用多个对象(例如机器人)时,集合非常有用。 CoppeliaSim不仅支持基于对象的计算,还支持基于集合的计算。 例如,碰撞检测模块允许登记以下冲突对:(集合A;对象B)。 然后,碰撞检查算法将检查集合A(组成它的任何对象)是否与对象B冲突。
集合是可碰撞、可测量、可检测和可呈现的实体。 这意味着集合:
即使集合是可碰撞、可测量、可检测和可渲染的,这也不意味着该集合中包含的所有对象都是可碰撞、可测量、可检测或可渲染的。
但是,集合可以覆盖其对象的可碰撞、可测量、可检测和可呈现属性。 有关更多详细信息,请参阅收集对话框。
集合必须至少由一个元素组成。 支持以下元素:
所有场景对象
该元素由所有场景对象组成,如下图所示(箭头表示子对象):
上面的元素没有任何定义对象,不能单独存在。 将其与其他类型的图元组合。
松散物体
这是场景对象的松散定义组合,如下图所示(箭头表示子对象):
在上面的示例中,如果从场景中移除对象2、对象3、对象4和对象7,则元素将不再有效,并且也将被移除。 对象2、对象3、对象4和对象7是元素的定义对象。
树,包括基座
这包括对象及其所有子对象(以及子对象的子对象等)。 如下图所示(箭头表示子对象):
在上面的示例中,如果从场景中移除对象1,则该元素将不再有效,并且也将被移除。 对象1是元素的定义对象。
树,不包括基部
这包括所有子对象(以及子对象的子对象等)。 没有对象本身的对象,如下图所示(箭头表示子对象):
在上面的示例中,如果从场景中移除对象1,则该元素将不再有效,并且也将被移除。 对象1是元素的定义对象。
链条,包括尖端
它包括一个对象及其所有父对象(以及父对象的父对象等)。 如下图所示(箭头表示子对象):
在上面的示例中,如果从场景中移除对象6,则该元素将不再有效,并且也将被移除。 对象6是元素的定义对象。
链条,不包括尖端
这包括对象的所有父对象(以及父对象的父对象等),而不包括对象本身,如下图所示(箭头表示子对象):
在上面的示例中,如果从场景中移除对象6,则该元素将不再有效,并且也将被移除。 对象6是元素的定义对象。
元素组合
在集合中,元素可以是加法元素,也可以是减法元素。 下图显示了一个由三个元素定义的集合:
在上面的示例中,结果集合包含两个对象。 如果将新对象附加到对象2或对象4,则不会将其包括在集合中(因为它将是元素2中定义的树的一部分,元素2是减法的)。 如果新对象成为对象5、对象3或对象1的父级,则不会将其包括在集合中(因为它将是元素3中定义的链的一部分,元素3是减法的)。 否则,新对象将自动包括在集合中。 集合是动态实体,会自动重新计算或更新。 当复制或保存对象(也是集合的定义对象)时,也会自动复制或保存相关的集合。
明智地使用集合,并且只有在找不到其他选择的情况下才这样做。 例如,如果要测试移动机器人是否与场景中的所有其他对象发生碰撞,则可以定义机器人集合(树从机器人基础开始)和障碍集合(所有场景对象-树从机器人基础开始),然后针对收集障碍测试收集机器人是否存在碰撞。 这可以很好地工作,但实际上并不需要障碍物集合:实际上,碰撞检测模块允许针对场景项目中的所有其他可碰撞对象指定检查。
当选择了集合中包含的所有对象时,集合将以粉色(可以在用户设置对话框中调整的默认颜色)突出显示,如下图所示。
可以在集合对话框中定义集合。
集合对话框位于[菜单栏–>工具–>集合]。 或者,也可以通过其工具栏按钮进行访问: