英文原版网址https://www.coppeliarobotics.com/helpFiles/index.html
结尾留了转换成PDF格式的百度云下载链接,里面配图都是正常显示的。有什么翻译错误望告知,请在评论区留言。
CoppeliaSim应用程序由几个元素组成。它的主要元素是:
控制台窗口:在Windows下,当CoppeliaSim应用程序启动时,会创建一个控制台窗口,但再次直接将其隐藏。隐藏控制台窗口的默认行为可以在用户设置对话框中更改。在Linux下,需要从控制台启动CoppeliaSim,该控制台在整个CoppeliaSim会话中始终可见。在MacOSX下,最好是从终端启动CoppeliaSim,以使消息可见。控制台或终端窗口显示了加载了哪些插件以及它们的初始化过程是否成功。控制台窗口不是交互式的,仅用于输出信息。用户可以使用Lua 打印将信息直接输出到控制台窗口命令(从脚本内部),或者从插件内部使用C printf或std :: cout命令。除此之外,用户还可以通过编程方式创建辅助控制台窗口,以显示特定于模拟的信息。
应用程序窗口:应用程序窗口是应用程序的主窗口。它用于显示,编辑,模拟场景并与之交互。在应用程序窗口中激活鼠标左右键,鼠标滚轮以及键盘具有特定功能。在应用程序窗口中,输入设备(鼠标和键盘)的功能可能会因上下文或激活位置而异。
几个对话框:在应用程序窗口旁边,用户还可以通过调整对话框设置或参数来编辑场景并与场景进行交互。每个对话框将一组相关功能或应用于同一目标对象的功能分组。对话框的内容可能是上下文相关的(例如,取决于对象选择状态)。
以下是CoppeliaSim应用程序的典型视图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pEssuUxY-1595242153694)(https://www.coppeliarobotics.com/helpFiles/en/images/userInterface.jpg)]
启动CoppeliaSim应用程序时,CoppeliaSim将初始化一个默认场景。用户可以自由地并行打开多个场景。每个场景与其他场景共享应用程序窗口和对话框,但是在应用程序窗口或对话框中只有活动的场景内容可见(在给定时间仅一个场景可见)。
在下一节中,将简要介绍应用程序窗口的元素。有关对话框的详细信息,请参阅本参考手册中的相关页面。
应用程序栏:应用程序栏指示您的CoppeliaSim副本的许可证类型,当前正在显示的场景的文件名,用于一次渲染过程(一次显示过程)的时间以及模拟器的当前状态(模拟状态或类型)活动编辑模式)。应用程序栏以及应用程序窗口内的任何表面也可以用于将与CoppeliaSim相关的文件拖放到场景中。支持的文件包括“ * .ttt”文件(CoppeliaSim场景文件)和“ * .ttm”文件(CoppeliaSim模型文件)。
菜单栏:菜单栏允许访问模拟器的几乎所有功能。大多数时候,菜单栏中的项目会激活一个对话框。菜单栏的内容是上下文相关的(即,它将取决于模拟器的当前状态)。也可以通过弹出菜单,双击场景层次结构视图中的图标或单击工具栏按钮来访问菜单栏中的大多数功能。
工具栏:工具栏提供经常访问的功能(例如,更改导航模式,选择其他页面等)。工具栏1中的某些功能以及工具栏2中的所有功能也可以通过菜单栏或弹出菜单访问。进一步了解更多细节。这两个工具栏都可以停靠和取消停靠,但是停靠仅适用于它们各自的初始位置。下图说明了每个工具栏按钮的功能:
[场景层次]
CoppeliaSim中的页面是场景的主要查看表面。它不是直接的视图,而是可以根据需要包含一个,两个或任意多个视图。视图是用来显示必须是可见对象的特定对象的图像内容的视图。例如,如果视图与相机对象相关联,则它可以显示相机看到的内容。下图说明了页面,视图和可见对象的关系:
视图在页面内可以具有固定位置,也可以在页面上具有浮动位置。以下页面配置说明了页面上方,视图和可见对象之间的关系:
CoppeliaSim中的 每个场景都有八个可自由配置的页面。可以通过页面选择器工具栏按钮访问(即显示)单个页面:
创建新场景时,将以不同方式预配置8个页面中的每个页面。可以使用[弹出菜单->删除页面]来删除页面。不存在的页面(即已删除的页面)显示暗灰色的表面。然后可以使用[弹出菜单->使用…设置页面]创建页面和具有空视图的默认页面配置。可以使用几种页面配置,如下图所示(数字表示视图索引):
以上页面配置允许显示1-8个固定视图。浅灰色表面中的每个对应于一个空视图(即未关联的视图)。任何时候都可以使用[弹出菜单->删除页面]来删除页面。删除页面还将删除其包含的所有视图,但不会删除任何关联的对象。在现有页面配置之上,可以使用[弹出菜单->添加->浮动视图]添加无限数量的浮动视图。下图显示了这样一个示例:
浮动视图可以移动和调整大小,但不允许使用鼠标左键或右键进行导航(例如,摄像机平移,摄像机旋转等)。双击一个浮动视图以将其内容与视图索引0交换(但是可以通过编程禁用它来禁止此操作)。要删除浮动视图,只需单击其右上角的按钮。
要将可查看对象与视图关联,请选择该对象,然后在要与之关联的视图上单击[弹出菜单->视图->将视图与所选摄像机关联]或[弹出菜单->视图->将视图与选定的视觉传感器关联](弹出菜单将根据最后选定的对象自动调整其内容)。创建视图但尚未与可见对象关联时,[弹出菜单->添加->摄像机]命令将添加摄像机并将其直接与视图关联(即浏览)。给定的可见对象可以同时与任意数量的视图关联。
或者,您还可以通过激活视图中的以下弹出窗口将视图与可见对象相关联:[弹出菜单->视图->视图选择器…]。这将打开视图选择器。
将查看对象与视图关联后,将显示其图像内容,但视觉传感器的工作方式除外:视觉传感器需要生成其图像内容,并且只有在调用适当的API命令时才会发生。默认情况下,主脚本包含一个将处理场景中所有视觉传感器的命令*(sim.handleVisionSensor(sim.handle_all))。除非将视觉传感器标记为显式处理*但未显式处理,否则它将在模拟过程中生成其图像内容。
可以通过以下方式自定义或调整与相机关联的视图:
由Federico Ferri提供的自定义UI插件(simExtCustomUI)提供了基于Qt框架的功能。该插件的源代码可以在https://github.com/CoppeliaRobotics/simExtCustomUI找到。
自定义UI插件提供Qt样式的小部件,例如集成按钮,编辑框,滑块,标签,图像等的对话框。对自定义UI的任何操作(例如,按钮单击,文本编辑,滑块移动)都将报告为脚本回调。其他功能可通过相关的API函数调用来访问。这样可以在很大程度上自定义仿真。以下显示了一个典型的自定义UI:
用户可以使用以下工具栏按钮之一来修改和操纵对象或项目的位置和方向 :
第一个显示位置对话框,第二个显示方向对话框。在这两种情况下,用户都将能够使用鼠标移动选定的对象或项目。
当选择对象转换工具栏按钮时,位置对话框变为可见:
该对话框具有四个不同的选项卡:
鼠标移动
在对话框的此部分中,可以设置用鼠标操作的对象的平移参数。另请参见有关通过鼠标移动对象的页面。
位置
在对话框的此部分中,可以在对象或项目上实现精确定位。
移动
在对话框的此部分中,可以实现精确的对象或项目移动。
位置缩放
在对话框的此部分中,可以实现对象或项目位置的精确缩放。
选择对象旋转工具栏按钮时,方向对话框将可见:
该对话框具有三个不同的选项卡:
鼠标旋转
在对话框的此部分中,可以设置用鼠标操作的对象的旋转参数。另请参见有关通过鼠标移动对象的页面。
取向
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSh57nQt-1595242153775)(https://www.coppeliarobotics.com/helpFiles/en/images/orientationDlg2.jpg)]
在对话框的这个部分,可以设置一个精确的对象方向。
旋转
在对话框的这一部分中,可以实现精确的对象旋转。
除了通过坐标和变换对话框修改对象配置之外,还可以使用鼠标直接操作对象:选择对象(和某些项目)后,可以使用以下工具栏按钮来平移或旋转对象:
默认情况下,在世界XY平面上执行平移。对于每个单个对象,还可以沿着不同的轴/平面并相对于不同的参考系执行此操作,具体取决于位置对话框中的设置。青色覆盖图表示当前平移平面或轴。
默认情况下,绕对象自己的Z轴执行旋转。对于每个单个对象,也可以围绕不同的轴或相对于不同的参考系执行此操作,具体取决于方向对话框中的设置。青色叠加图表示当前的旋转轴。
可以在用户设置对话框中调整默认的平移和旋转步长(捕捉),但建议分别保持5厘米和5度的值,或者分别设置对象的步长。在对象操作过程中按下鼠标按钮后,按住Shift键可以暂时禁用快照。以类似的方式,在对象操作过程中按下鼠标按钮后,按住ctrl键可以临时激活其他平移或旋转轴。
当模拟器处于顶点编辑模式或路径编辑模式时,也可以使用对象/项目转换工具栏按钮。
该欧拉角三个角度描述刚体的方向。在讨论欧拉角时,有十二种不同的约定。在CoppeliaSim中,欧拉角alpha,beta和gamma(或(a,b,g))描述了由三个基本旋转组成的旋转:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MsorIvlJ-1595242153784)(https://www.coppeliarobotics.com/helpFiles/en/images/eulerAngles.jpg)]
其中Rx,Ry和Rz分别表示绝对参考系围绕x,y和z轴的元素旋转。
对于刚体或场景对象,如果按以下顺序围绕其自身的参考帧旋转,则可以获得相同的变换:围绕自身X 旋转alpha,然后围绕自身Y 旋转beta,接着围绕自身旋转beta。关于自己Z的gamma。
CoppeliaSim中的某些值和设置不依赖于场景或模型,而是依赖于用户。用户设置对话框(部分反映文件system / usrset.txt的内容)可以通过[菜单栏->工具->设置]或单击以下工具栏按钮来访问:
OpenGL设置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QzBHrTMY-1595242153795)(https://www.coppeliarobotics.com/helpFiles/en/images/openGlSettings.jpg)]
当焦点位于场景层次结构或页面上时,支持以下快捷键:
通过命令行启动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”文件)还支持资源管理器窗口和应用程序窗口之间的拖放操作。也可以双击场景文件,在这种情况下,它们将启动CoppeliaSim应用程序并打开。
只需在场景层次结构的上部单击即可切换打开的场景(所有打开的场景都在场景层次结构的顶部分组),或者通过与其相关的工具栏按钮使用场景选择器来实现:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxBZ3f3r-1595242153808)(https://www.coppeliarobotics.com/helpFiles/en/images/sceneSelectorView.jpg)]
模型是场景的子元素。除了文件(“ * .ttm”-文件类型)外,模型本身不能存在,也不能通过自身进行模拟。模型必须包含在场景中才能运行。
模型是通过选择在同一层次树上构建的场景对象来定义的,其中树的基础必须是标记为object is model base的对象。可以通过[菜单栏->文件->加载模型…]来加载它们。但是,通过在模型浏览器和场景视图之间进行拖放操作来加载模型更加容易和方便。可以使用[菜单栏->文件->将模型另存为…]保存模型,只需确保选择了一个标记为对象为模型库的单个对象,否则**将模型另存为…-**菜单项未启用。还请确保遵循有关如何构建清晰仿真模型的教程。
通过以下步骤定义模型:
现在,无法再在场景中选择建立在模型基础上的单个对象(选择它们将改为选择模型的基础),但是仍然可以通过在选择过程中按住ctrl和Shift键来单独选择它们,或者通过在场景层次中选择它们。除此之外,当选择基础对象时,将显示一个包围整个模型的点画边界框,如下图所示:
注意标记为模型库的对象图标左侧的模型标签:
双击模型标签可打开模型对话框,可在其中调整模型属性。修改模型的层次结构后,最好折叠模型的层次结构,以轻松识别逻辑分组的元素/模型的数量:
当子脚本以编程方式访问对象时,将多个对象分组为模型也很重要。请记住,在CoppeliaSim中,对象/模型可以随时复制,也可以在仿真过程中复制。为了使重复的子脚本能够访问正确的对象(不是原始对象,而是重复的对象),应始终在访问子脚本的同时复制子脚本。保证的一种方法是创建模型(如上所述),并确保访问模型中对象的子脚本与模型中包含的对象相关联。最好是将一个子脚本(也可能有第二个子脚本)与模型的基础关联。请参阅以编程方式访问对象部分 想要查询更多的信息。
为了使模型易于组合(即彼此构建)而不进行任何其他修改,重要的是要考虑模型将扮演什么角色:可以动态模拟吗?它会被附加到其他型号,还是会接受其他附加模型?这些问题的答案将使您能够选择最佳的对象类型作为模型基础。有关更多信息,请参考设计动态仿真部分。
复制和粘贴模型的行为与保存模型,然后加载(就像使用内存缓冲区而不是磁盘空间)一样。可以将模型从一个场景复制到另一个场景,就像其他对象一样。模型文件(“ * .ttm”文件)还支持资源管理器窗口和应用程序窗口之间的拖放操作。还可以双击模型文件,在这种情况下,它们将启动CoppeliaSim应用程序并加载到默认场景中。
可以在模型对话框中单独调整模型的属性。
可以在模型对话框中单独调整模型的属性。可以双击场景层次中的模型图标来打开它:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USFw8Rfh-1595242153823)(https://www.coppeliarobotics.com/helpFiles/en/images/objectCommonDlg3.jpg)]
CoppeliaSim中的环境定义属性和参数,这些属性和参数是场景的一部分,但不是场景对象。保存模型时不保存环境属性和参数,而仅保存场景时不保存。
环境定义以下属性和参数:
可以通过[菜单栏->工具->环境]或通过双击场景层次结构中的以下图标来访问环境对话框:
纹理对话框允许您查看和修改与附加到形状的纹理相关的属性。通过在形状属性对话框中单击**设置纹理-**项可以访问它:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16ZEOCt7-1595242153830)(https://www.coppeliarobotics.com/helpFiles/en/images/texture1.jpg)]
纹理是可以应用于表面以使其看起来更真实的位图图像。想象一下,在矩形表面上应用砖纹理以使其看起来像砖墙。下图说明了带纹理的表面:
CoppeliaSim将纹理应用到形状的默认方式是将其投影到形状的x / y平面上,如下图所示:
支持以下5种纹理映射方法:
下图说明了5种映射方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DFrschhm-1595242153840)(https://www.coppeliarobotics.com/helpFiles/en/images/texture6.jpg)]
加载新纹理时,将打开以下对话框:
建议保留默认设置,以保持与旧图形卡的较高兼容性(选中“将纹理**缩放至”**时,无论如何将所有纹理的大小调整为2的幂),并且文件大小较小。
一旦纹理存储在内存中,就可以在实际映射发生之前对其进行缩放,移动和旋转,以获得所需的视觉外观。
可以通过单击“ **加载新纹理”**按钮来加载静态纹理。当前支持以下文件格式:
除了从文件中加载纹理,您还可以选择已加载的静态纹理,甚至选择视觉传感器生成的动态纹理。只需单击“ **从现有纹理中选择纹理”**按钮。请注意,动态纹理将仅在模拟期间正确显示(并且只有在正确处理了相关视觉传感器的情况下,才显示)。
实体是指场景对象或集合的术语。下图说明了场景对象,集合和实体之间的关系:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NN2guhRK-1595242153845)(https://www.coppeliarobotics.com/helpFiles/en/images/entities1.jpg)]
CoppeliaSim提供了强大的计算功能或计算模块,这些功能或功能没有直接封装在对象中(例如,接近传感器或视觉传感器),而是对一个或多个对象进行操作。
计算模块包括:
其他类似功能也可以通过插件提供,例如使用路径/运动计划插件。
一些计算模块允许注册 用户定义的计算对象。计算对象不同于场景对象,但通过对其进行操作而间接链接到它们。这意味着计算对象不能单独存在:
如果在场景对象的复制/粘贴操作期间维护了给定计算对象的完整性,则该计算对象也将被自动复制。例如,如果碰撞对象A由可碰撞对象B和可碰撞对象C定义(即,在对象B和对象C之间执行碰撞检测),并且如果对象B和C同时复制(在同一复制粘贴中)操作),则碰撞对象A也将被复制。这代表了一项强大的功能,它不仅可以复制对象或模型,还可以复制其所有相关的计算对象(包括所有相关的脚本)),以便可以维护对象或模型的全部功能和行为。
所述计算模块属性对话框位于[菜单栏- >工具- >计算模块属性。您还可以通过单击其工具栏按钮来打开对话框:
计算模块属性对话框显示与计算模块相关的属性。该对话框分为4部分:
对话框上部的4个按钮允许选择想要显示的属性类型:
CoppeliaSim可以非常灵活的方式检测两个可碰撞 实体之间的碰撞。该计算是精确的干扰计算。碰撞检测模块将仅检测碰撞。但是,它不会直接对它们做出反应(有关碰撞响应,请参考动力学模块)。下图说明了冲突检测功能:
碰撞检测模块允许注册作为可碰撞实体对(碰撞实体和碰撞实体)的碰撞对象。在仿真过程中,每个已注册的碰撞对象的碰撞状态然后可以使用不同的颜色可视化,或记录在图形对象中。有关如何记录碰撞状态的更多信息,请参考图形和图形数据流类型。如果已注册的碰撞对象在复制粘贴操作中同时复制了它们的两个组成实体,则会自动复制(复制)它们。
碰撞检测模块中使用的碰撞检测例程也可以通过Coppelia几何例程作为独立例程使用。
碰撞检测对话框是计算模块属性对话框的一部分,该对话框位于[菜单栏->工具->计算模块属性]。您还可以通过单击其工具栏按钮来打开对话框:
在计算模块属性对话框中,单击“ **碰撞检测”**按钮以显示碰撞检测对话框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q7WE7rsj-1595242153864)(https://www.coppeliarobotics.com/helpFiles/en/images/collisionDetection3.jpg)]
CoppeliaSim可以非常灵活的方式测量两个可测量 实体之间的最小距离。该计算是精确的最小距离计算。距离计算模块将仅测量距离;但是它不会直接对他们做出反应。下图说明了距离计算功能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ANuO7x4-1595242153868)(https://www.coppeliarobotics.com/helpFiles/en/images/distanceCalculation1.jpg)]
距离计算模块允许注册作为可测量实体对的距离对象。在仿真过程中,每个可视距离对象的最小距离段然后可以可视化或记录在图形对象中。有关如何记录距离对象的更多信息,请参考图和图数据流类型。如果在复制粘贴操作中同时复制了两个距离实体,则已注册的距离对象将自动复制(复制)。
最小距离计算模块中使用的距离计算例程也可以通过Coppelia几何例程作为独立例程使用。
距离计算对话框是计算模块属性对话框的一部分,该对话框位于[菜单栏->工具->计算模块属性]。您还可以通过单击其工具栏按钮来打开对话框:
在计算模块属性对话框中,单击距离计算按钮以显示距离计算对话框:
CoppeliaSim的逆运动学(IK)计算模块非常强大且灵活。它允许以逆运动学模式(IK模式)或正向运动学模式(FK模式)处理几乎任何类型的机构。IK问题可以看作是找到与给定身体元素(通常是末端执行器)的某些特定位置和/或方向相对应的关节值之一。更一般而言,它是从任务空间坐标到关节空间坐标的转换。例如,对于串行操纵器,问题将是找到所有关节的值给出末端执行器的位置(和/或方向)后,在操纵器中的位置。反问题-在给定关节值的情况下找到末端执行器的位置-被称为FK问题,通常被认为比IK更容易完成。在处理开放式运动学链时,这确实是正确的,但对于一般类型的机械配置却不成立,例如以下所示:
逆运动学计算模块的某些结果可以由图形对象记录。有关如何记录逆运动学计算数据的更多信息,请参考图和图数据流类型。
运动学功能也可用于独立应用程序(即,不直接属于CoppeliaSim框架的应用程序,例如另一台计算机,机器人或控制器上的应用程序)。这是通过Coppelia运动学例程实现的。
最后,确保在文件夹scenes / ik_fk_simple_examples中查看与IK和FK相关的各种简单示例场景。
CoppeliaSim使用IK组和IK元素解决逆向和正向运动学任务。重要的是要了解如何解决IK任务,以便充分利用模块的功能。确保在文件夹scenes / ik_fk_simple_examples中查看与IK和FK相关的各种简单示例场景。IK组包含一个或多个IK元素:
IK元素由运动链和要遵循的目标指定。运动链本身由工具提示(或末端执行器,或简称为尖端)指定,该提示指示链中的最后一个对象,而基部指示链中的基础对象(或第一个对象)。下图显示了为IK元素指定的两条运动链。IK元素以相似的方式感知两条链(第二个示例的第一个关节被IK元素忽略):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mL2B2tZY-1595242153881)(https://www.coppeliarobotics.com/helpFiles/en/images/ikBasics1.jpg)]
在上面的示例中,由尖端/基部对指定的运动链都具有3个自由度(DoF),因为其中涉及3个1-DoF关节。但是,如果其中一个关节是球形关节,则该链将具有5 DoF,因为球形关节本身具有3 DoF。
现在,您应该告诉IK元素,指定的运动链在仿真期间应如何表现。通常,您希望运动链的尖端跟随目标(请参阅虚拟属性以形成尖端与目标的链接):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-alOZEaDP-1595242153883)(https://www.coppeliarobotics.com/helpFiles/en/images/ikBasics2.jpg)]
当模拟运行并且正确定义了一些其他参数(请参阅下文中的参数说明)时,机制(指定的运动学链)应朝目标移动。这是IK任务的最基本情况。两个单独的运动链以相同的方式处理,但是这一次,需要两个IK组(每个运动链中的每个IK元素都应包含一个IK元素)。两个IK组的求解顺序并不重要:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tF3Mqocb-1595242153895)(https://www.coppeliarobotics.com/helpFiles/en/images/ikBasics3.jpg)]
在上面的示例中,应该将target2附加到第一个运动链的可移动部分,然后求解顺序变得很重要,并且应该首先求解IK group1(解决结果将取代target2,如下图所示):
当一个IK元素建立在另一个IK元素之上而没有共享任何共同关节时,可能会出现类似情况,如下图所示:第一个运动学链用黑色表示,第二个运动学链用浅蓝色表示。紫色表示的Base2是两条链之间的公共对象。解决IK element2不会替换紫色链接,但是解决IK element1会替换紫色链接。因此,与上述情况一样,必须在IK group2之前解决IK group1(解决顺序很重要):
当两个或多个运动链共享共同的关节时,会出现更困难的情况。在这种情况下,顺序求解在大多数情况下不起作用(在以下示例中,两个IK元素倾向于将公共关节旋转到相反的方向),因此需要同时求解方法。要同时求解多个IK元素,只需将它们分组为一个公共IK组。下图说明了这种情况:
通过使用IK组和IK元素解决了机构的反向运动学(IK)或正向运动学(FK)(请参阅关于IK组和IK元素的基础知识部分)。牢记以下检查点,以便成功设置IK或FK计算:
最后一点很重要,必须理解:已打开所有约束的运动链尖端将在x,y,z方向上遵循其关联的目标,同时尝试保持与目标相同的方向。但是,只有在运动链具有至少6个非冗余自由度(DoF)的情况下,此方法才有效。提示应始终受到适当的约束(即,永远不要指示比该机制中存在DoF的约束更多的约束)。位置约束在大多数情况下是相对于基座方向指定的,如下图所示:
但是,有时无法正确指定尖端的约束,在这种情况下,IK组的计算方法应为具有适当选择的阻尼系数的阻尼方法(例如DLS方法)。当无法达到目标(无法达到或接近单一配置)时,也应选择阻尼分辨率方法。阻尼可以使计算更稳定,但请记住,阻尼始终会降低IK计算的速度(需要进行多次迭代才能将笔尖放置到位)。
启用Alpha-Beta约束将使笔尖的z轴方向与目标的z轴方向匹配,如果关闭了Gamma约束,则保持绕z轴的自由旋转。启用Alpha-Beta约束和Gamma约束时,尖端将尝试采用与其关联目标完全相同的方向。
在关于IK组和IK元素的基础知识部分中,介绍了解决简单运动链的IK问题的步骤。解决简单运动链的FK问题是微不足道的(只需将期望的关节值应用于链中的所有关节即可获得尖端或末端执行器的位置和方向)。解决封闭机构的IK和FK问题不是那么简单。
解决IK和FK的封闭机构
在下一节中,将讨论两个一般示例,这些示例应使用户能够理解解决一般类型封闭机制的方法:
在FK问题的情况下,首先确定要控制的关节(即,驱动机械的关节,活动关节)。这些关节应从所有运动学计算中排除(选择与逆运动学模式不同的关节模式(请参见关节属性))。从现在开始,通过运动学计算,这些接头将被认为是刚性的。然后,确定需要关闭的运动链。关闭将通过以尖端-目标对的形式的循环闭合约束进行处理,如下图所示:
然后,为活动关节设置所需的关节值,并调用逆运动学功能来处理回路闭合约束。(默认的主脚本处理所有未标记为显式处理的 IK组)。
以下示例显示了一些可用于解决复杂运动学问题的附加功能:
从图中可以看出,用户需要执行一项IK任务:将笔尖放在目标上(或让笔尖跟随目标)。这可以通过常规方式解决,或者用户可以使用联合依赖功能。下图说明了这一点:
IK的主要任务是达到目标,回路闭合约束负责闭合机构,关节重叠约束负责保持机构的基础重叠(作为一条链)。关节相关性线性方程的参数必须仔细选择才能达到完美的重叠(例如,如果两个相应的关节(通过重叠约束链接的关节)具有相同的方向,则需要设置方程中的系数到-1!(因为一个关节是自下而上构建的,而另一个关节是自上而下构建的))。
大多数时候,有多种方法可以解决一种机构的IK或FK,在实施最复杂的替代方案之前,总是值得考虑各种替代方案!
运动学逆对话框是计算模块属性对话框的一部分,该对话框位于[菜单栏->工具->计算模块属性]。您还可以通过单击其工具栏按钮来打开对话框:
在计算模块属性对话框中,单击“ **逆运动学”**按钮以显示逆运动学对话框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0Mold96-1595242153922)(https://www.coppeliarobotics.com/helpFiles/en/images/ikDialog2.jpg)]
启用了反向运动学:启用或禁用所有反向运动学计算。
添加新的IK组:添加一个新的空IK组。IK组可以包含一个或多个IK元素。IK元素是基本的运动链IK任务,并且IK组可以将它们分组以同时求解。仅在需要时才使用同时求解(比顺序求解更长的计算时间)。IK元素始终必须与IK组相关联,并且本身不能存在。按钮下方的列表显示了将在IK计算期间求解的所有IK组。需要选择列表中的IK组,以便在对话框的其余部分中可视化其参数。列表中的顺序很重要(IK组2可能需要IK组1的结果才能正确执行或更快地执行)。列表旁边的两个按钮允许更改所选IK组的位置。
IK组处于活动状态:允许打开和关闭单个IK组。
显式处理:指示是否应显式处理所选的IK组。如果选中,则在调用sim.handleIkGroup(sim.handle_all_except_explicit)时将不处理该IK组的IK计算,仅在调用sim.handleIkGroup(sim.handle_all)或sim.handleIkGroup(ikGroupHandle)时才进行。如果用户希望在子脚本中而不是在主脚本中处理该IK组的运动学,这将很有用(如果未选中,则在sim.handleIkGroup(sim.handle_all_except_explicit)一次将处理该IK组的IK计算两次。在主脚本中被调用,并且在子脚本中被调用sim.handleIkGroup(ikGroupHandle)时被调用一次。另请参阅有关显式和非显式调用的部分。
机制是多余的:选择该选项后,将在IK分辨率期间应用关节极限校正。否则,将仅在IK解析后强制执行联合限制,这可能会导致不稳定。
忽略最高 步长:如果选中此属性,则将忽略在关节属性中指定的最大步长。
计算 method:用于指定IK组分辨率的计算方法。伪逆是最快的方法,但是当目标和尖端之间的距离太远,运动链受到过度约束或机制接近单一配置或目标无法到达时,伪逆可能会变得不稳定。DLS较慢但更稳定,因为它是一种阻尼分辨率方法(可以指定阻尼因数(阻尼))。当伪逆方法可能失败时,这是一个不错的选择。
阻尼:使用阻尼分辨率方法(DLS)时的阻尼系数。较大的值可导致更稳定的分辨率,但速度慢得多。适当调整此值很重要。
最高 迭代次数:可以指定最大迭代次数。这是给定IK组的最大计算通过次数,直到达到指定的分辨率精度为止。与非阻尼分辨率(伪逆)相比,阻尼分辨率(DLS)通常需要更多的迭代。
关节极限(计算权重):应该用于关节限制约束的计算权重(关节限制约束在关节属性(最小位置和位置范围)中指定。
避障(计算权重):应用于避障约束的计算权重。
关节极限阈值:应与关节极限约束一起使用的线性和角度阈值。
编辑条件参数:允许为选定的IK组调整条件分辨率参数。将弹出以下对话框:
编辑避障参数:允许调整避障参数。请注意,这仅对冗余操纵器有意义,并且仿真速度可能会大大降低。将弹出以下对话框:
编辑IK元素:允许相对于选定的IK组编辑各种IK元素。单击此按钮将打开IK元素对话框。
IK元素对话框是逆运动学对话框的一部分。该对话框显示给定IK组的各种IK元素。在“ 逆运动学”对话框中,选择一个IK组,然后单击“ **编辑IK元素”**按钮以打开IK元素对话框:
CoppeliaSim的动力学模块当前支持四种不同的物理引擎:Bullet物理库,Open Dynamics引擎,Vortex Studio引擎和Newton Dynamics引擎。在任何时候,用户都可以根据自己的仿真需求自由地从一种发动机快速切换到另一种发动机。物理引擎支持如此多样化的原因是,物理模拟是一项复杂的任务,可以通过不同程度的精度,速度或支持多种功能来实现:
动态模块允许模拟之间的相互作用对象是接近真实世界的物体相互作用。它可以使物体掉落,碰撞,反弹,但也可以使机械手抓住物体,用传送带将零件向前推动,或者使车辆在不平坦的地形上以逼真的方式滚动。下图说明了动态仿真:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJA4Aasb-1595242153950)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamics2.jpg)]
与许多其他仿真软件包不同,CoppeliaSim并非纯粹的动力学模拟器。可以将其看作是一种混合模拟器,它结合了运动学和动力学特性,以便在各种模拟情况下获得最佳性能。如今,物理引擎仍依赖于许多近似值,并且相对不精确且缓慢,因此,只要有可能,您应尝试使用运动学代替(例如,对于机器人操纵器),而仅依靠动力学,否则就不可行(例如,机器人操纵器的夹具)。如果要模拟的移动机器人不应该与环境发生碰撞或物理交互(无论如何,大多数移动机器人都很少这样做),并且该移动机器人只能在平坦的地面上运行(将绝大多数移动机器人分组) ,然后尝试使用运动学或几何计算来模拟机器人的运动。
动力学模块的某些结果可以由图形对象记录。有关如何记录动态数据的更多信息,请参考图形和图形数据流类型。
在CoppeliaSim中,将仅动态模拟有限数量的对象。这些是形状,关节和力传感器,但是这将取决于场景结构和对象属性,是否会动态模拟给定的对象。在仿真过程中可以轻松识别动态仿真的对象,因为在场景层次结构中,对象名称旁边会出现以下图标:
双击场景层次中的图标(仅在仿真过程中)将显示一些与对象的动态行为有关的信息。动态模拟应该具有但由于某种原因而不能动态模拟的对象将改为显示以下图标:
静态/非静态,可响应/不可响应的形状
根据形状在动态模拟中的行为,可以将其分为4组:
在动态仿真过程中,静态形状将不受影响(即,它们相对于其父对象的位置是固定的),而非静态形状将直接受到重力或其他约束的影响(例如,动态启用的关节,请参见下文)。负责任的形状在动态碰撞过程中会相互影响(即,它们会产生相互碰撞的反应,它们会相互反弹)。下图说明了静态/非静态,可响应/不可响应行为:
除非它们各自的碰撞蒙版不重叠,否则两个可响应的形状将始终产生碰撞反应。可以在“ 形状动力学”属性对话框中设置静态/非静态,可响应/不可响应的形状属性以及碰撞蒙版。
动态启用的关节/力传感器
如果非静态形状不受其他限制,它们将掉落(即受重力影响)。可以通过将两个形状与可动态启用的 关节或可动态启用的 力传感器连接在一起来设置形状之间的动态约束。
动态启用的关节是处于力或扭矩模式或以混合方式运行的关节(请参见关节属性),并且具有作为父对象的形状和恰好必须是非静态形状的一个子对象的形状。另外,有可能使接头处于闭环构造中。在那种情况下,关节必须通过虚拟的虚拟链接连接到两个形状(链接类型必须为Dynamics,重叠约束)。有关虚拟虚拟链接,请参阅虚拟属性。
动态启用的力传感器是具有形状作为父对象和正好一个子对象(必须是非静态形状)的力传感器。另外,可以将力传感器包括在回路闭合构造中。在那种情况下,力传感器必须通过虚拟的虚拟链接连接到两个形状(链接类型必须为Dynamics, overlapstriction )。有关虚拟虚拟链接,请参阅虚拟属性。
下图显示了将关节或力传感器视为动态启用的有效情况(假设关节/力传感器和两个形状位于动态模拟的模型中,这是默认情况):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lC9Yunk4-1595242153967)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamicsDesign5.jpg)]
请遵循上述准则,以获取动态启用的关节或力传感器,这一点非常重要。在模拟过程中,如果CoppeliaSim发现未动态启用的力传感器,它将在场景层次视图中其名称旁边显示一个小的警告图标。在力/扭矩模式下的关节或应该以混合方式操作且没有动态启用的关节也会发生同样的情况。
以下是无法动态启用关节的一些示例情况:
以下是一些无法动态启用力传感器的示例情况:
硬质化合物
未通过动态启用的关节或力传感器链接的两个非静态形状将在动态仿真过程中彼此独立移动。如果希望两个或多个形状表现为一个形状,则必须将它们分组(菜单栏->编辑->分组/合并->分组选定的形状)。确保适当调整最终形状的惯性矩。确保您还仔细阅读了有关纯形状的部分:
复合形状将表现为刚性实体,并且也具有相同的动力学特性(例如,摩擦系数)。有时需要具有动态特性的刚性实体。在这种情况下,必须通过力传感器将形状刚性连接。这种结构的刚度不如复合形状强,但在大多数情况下效果良好:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bomlb6db-1595242153975)(https://www.coppeliarobotics.com/helpFiles/en/images/forceSensorRigidLink.jpg)]
通过使两个形状通过两个链接的虚拟对象链接起来,可以获得相似的结果。两个假人的链接类型必须为“ 动态”,“重叠约束”(请参阅“ 虚拟属性”)。在动态仿真期间,两个链接的虚拟对象将尝试采用相同的位置和方向。下图显示了用于动态仿真的有效刚性回路闭合约束:
设计注意事项1
**使用纯净的形状。**只要有可能,请尝试将纯形状用作可响应形状:在动态仿真过程中,纯形状会更加稳定且速度更快。与其使用复杂的机器人模型三角形网格作为可响应的形状或更好的凸形表示,不如尝试用几个纯形状近似三角形网格,然后将它们分组[菜单栏->编辑->分组/合并- >对选定的形状进行分组](请注意,如果您合并纯形状而不是对它们进行分组,则生成的形状将不再是纯形状)。下图说明了机器人隐藏的可响应纯形状:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vo0r233o-1595242153995)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamicsDesign10.jpg)]
从复杂的非纯形状中提取纯形状的一种简便方法是,进入复杂形状的三角形编辑模式,然后选择感兴趣的区域并提取矩形,球形或圆柱形的纯形状。请参阅三角形编辑模式下的“ 提取长方体”,“ 提取圆柱体 ”和“ **提取球体”**按钮。确保您还阅读了有关导入和准备刚体的教程。使用动态内容可视化工具栏按钮可视化和验证场景的动态内容也是一种好习惯(请参阅设计注意事项3)。
当物体可以碰撞但不能持续碰撞,或者在机械/机器人的稳定性中不发挥重要作用时,则不一定非要使用纯形状,凸形也可以是可行的替代方案:
设计考虑2
**使用凸形状代替随机形状。**尽可能使用纯形状作为可响应形状(请参阅设计注意事项1)。但是,这并不总是那么容易做到,也不是实用的(例如,想像一个圆环)。在那种情况下,您可以生成凸形或凸形分解形(即仅包含凸形网格的简单/复合形状)。凸形状比随机形状执行得更快并且更稳定(但是它们仍然不如纯形状快和稳定!)。
选择要简化为凸形的形状,然后选择[菜单栏->编辑->将所选形状变形为凸形…]。另请参阅项目[菜单栏->添加->选定形状的凸分解…]。下图说明了凸分解:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eepc0fiT-1595242153998)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamicsDesign15.jpg)]
设计考虑3
仔细检查场景的动态内容。有时,要在模拟中发挥积极作用的隐藏形状可能会有些混乱。动态启用的形状,关节或力传感器通常是这种情况:实际上,它们大多数时候都隐藏在观察者的眼中。但是,始终可以在仿真期间通过激活动态内容可视化按钮来检查动态内容:
动态对象将根据其功能或设置以各种颜色显示。请参考下图:
注意上图中非纯形状的外观:它们的三角形网格轮廓以绿色或灰色表示。应该不惜一切代价避免使用动态模拟的非纯形状,因为它们需要更长的计算时间,并且呈现出不太稳定的行为(但是,凸形比非凸形更快,更稳定)。另请参考上面的设计注意事项1。
设计考虑4
使用简单的层次结构。建立要动态模拟的模型时,请将所有非动态对象附加到动态对象(非静态形状和动态启用的关节)。上面的轮式机器人模型如下图所示:
设计考虑5
仔细选择模型基础对象。在构建动态模型时,实际上在构建静态模型时,始终要谨慎考虑模型将扮演什么角色。是否可以单独使用?它可以建立在另一个模型或对象之上吗?还是可以接受其他要在其之上构建的模型或对象?考虑以下示例:
您已经创建了移动机器人的模型。您还创建了夹具的模型。显然,您希望能够轻松地将抓手模型附加到机器人模型的顶部。相反,将永远都没有意义(将机器人模型附加在抓具模型之上)。您可能还想单独使用机器人模型和机械手模型。以下是可能的模型定义的场景层次结构视图:
注意“机器人”和“夹具”形状对象旁边的模型图标。这表明在它们之上构建的所有对象都是同一模型定义的一部分。两种模型各自运行良好。但是,如果尝试将夹持器连接到机器人顶部(通过选择夹持器模型,然后选择机器人模型,然后单击[菜单栏->编辑->使上一个选定的对象成为父对象]),则夹持器将不会在仿真过程中保持固定在机器人上。以下是上述两个模型的场景层次结构,其中机械手已连接到机械手:
请注意,在上述场景层次中,纯形状 “抓取器”是如何在纯形状“机器人”之上构建的。并记住,如果不通过力传感器的连接加以限制,非静态形状将会掉落……确切地说,我们需要在“夹具”和“机器人”之间安装一个力传感器,以使两者之间具有牢固的连接!
机器人的正确模型定义必须包括抓具的连接点(或其中几个),如下图所示:
固定点是一个简单的力传感器。将抓具模型与上述机器人模型组装在一起,将使抓具相对于机器人保持固定:
为了进一步简化装配过程,您可以自定义装配工具栏按钮的行为,以便以正确的相对位置/方向将抓具自动放置到附着点上。有关更多详细信息,请参见有关模型的部分以及对象公共属性中的对话框项“ 组装 ” 。
设计考虑6
使用合理的尺寸。形状太长,太细或太小可能会表现出奇怪的现象(抖动,跳跃)。如果可能,请尝试将尺寸保持在3厘米以上。否则,您可以在动态引擎常规属性对话框中调整内部缩放参数。
设计考虑7
保持肿块相似且不要太轻。使用动态启用的关节或动态启用的力传感器链接两个形状时,请确保两个形状的质量没有太大差异(m1 <10 * m2和m2 <10 * m1),否则,关节或力传感器可能会非常柔软和不稳定和本大的位置/取向的错误(此效果然而,也可以用作天然阻尼有时)。此外,应避免质量过低的形状,因为它们无法将很大的力施加到其他形状上(即使由强力执行器推动!)。
设计考虑8
保持主要转动惯量*较大。尝试使主要的惯性矩/质量(*请参见“ 形状动力学属性”对话框)相对较大,否则机械链条可能难以控制和/或表现出奇怪的行为。
设计考虑9
将动态形状分配给第9层。将所有应隐藏的动态形状分配给第9层(请参阅对象的公共属性):在CoppeliaSim中,默认情况下,除第9-16层外,所有层都是可见的。在编辑或测试场景时,可以通过临时启用第9层(另请参阅层选择对话框)来快速可视化场景中所有隐藏的形状。
设计考虑10
在两个动态项目之间绝对不能有静态形状。静态形状将中断动态链的逻辑行为:
设计考虑11
在动态项目的顶部绝对不要有静态的可响应形状。静态意味着形状的轨迹不会受到任何碰撞的影响,但是如果它同时是可响应的,则意味着它本身可以通过碰撞影响其他形状的轨迹。仿真结果将是不可预测的。
常规动力学属性对话框是计算模块属性对话框的一部分,该对话框位于[菜单栏->工具->计算模块属性]。您还可以通过单击其工具栏按钮来打开对话框:
在计算模块属性对话框中,单击“ **动力学”**按钮以显示常规动力学属性:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cggD4psQ-1595242154035)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamicsDialog2.jpg)]
启用动态:允许启用/禁用整个场景的动态计算。
使用的引擎:要使用的动力学引擎。Bullet代表Bullet物理库,ODE代表Open Dynamics引擎,Vortex代表Vortex Studio引擎,Newton代表Newton Dynamics引擎。每个引擎都有其特定的优点和缺点。在一个引擎上运行良好的模拟并不总是意味着在其他引擎上也运行良好。每个引擎都有特定的参数,这些参数可以全局设置(请参阅下文中的“ 调整引擎参数”),也可以在局部设置(在与接头有关的材料属性或动力学引擎属性对话框中))。确保阅读相应的引擎文档,以实现最佳参数设置。
显示接触点:允许显示可响应形状之间的接触点。
调整引擎参数:打开“ 动力学引擎常规属性”对话框,该对话框允许调整引擎特定的全局参数。
重力:施加于所有非静态形状(例如重力)的恒定力的幅度和方向。
动态引擎常规属性对话框是常规动力学属性对话框的一部分。该对话框显示引擎配置和各种引擎特定的全局属性。在常规动力学属性对话框中,单击调整引擎参数按钮以打开以下对话框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LKRn3g3Q-1595242154038)(https://www.coppeliarobotics.com/helpFiles/en/images/dynamicsEngineDialog.jpg)]
每个引擎都有特定的参数,可以在全局(请参阅下文)或局部(在与接头有关的材料属性或动态引擎属性中)设置特定参数。
子弹属性
与Bullet物理库有关的属性。请确保还参考Bullet用户手册以获取详细信息。
ODE属性
与Open Dynamics Engine相关的属性。请确保还参考ODE用户手册以了解详细信息。
涡流特性
与Vortex Studio引擎相关的属性。确保还参考Vortex用户手册以了解详细信息。
牛顿性质
与牛顿动力学引擎有关的属性。确保还参考牛顿用户手册以获取详细信息。
涡流附加信息
使用引擎约束属性可使所有约束更柔和,从而有助于避免数值不稳定。对于涉及非常大质量的模拟,可能必须减少约束松弛。这些参数是全局参数,会影响所有约束和碰撞接触。对于单个约束松弛,您可以直接参考约束参数,其中每个约束方程式可以独立地松弛。对于因碰撞而引起的不稳定性,可以使用蒙皮厚度来平滑法向响应或增加滑移参数,以增加接触摩擦的粘度。对于轻质刚体的链条和承受较大拉力的约束,例如用于抓取比手指大几个数量级的物体的手动机构,
CoppeliaSim是高度可定制的模拟器:一个的每一个方面模拟可定制。此外,模拟器本身可以进行定制和定制,以使其性能完全符合要求。这可以通过精心设计的应用程序编程接口(API)来实现。支持六种不同的编程或编码方法,每种方法都具有相对于其他方法的特殊优点(显然还有缺点),但所有六种方法都是相互兼容的(即可以同时使用,甚至可以手拉手使用)。模型,场景或模拟器本身的控制实体可以位于以下位置:
外部控制器教程 中还讨论了上述6种方法。下表详细描述了每种方法的各自优点和缺点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ozTNOxAK-1595242154041)(V-rep中文.assets/controlEntities.jpg)]
下图说明了CoppeliaSim及其周围的各种自定义可能性:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hvKgFSWJ-1595242154044)(https://www.coppeliarobotics.com/helpFiles/en/images/writingCode1.jpg)]
以下简要描述了上图中指示的各种通信或消息传递机制:
CoppeliaSim是一个高度可定制的模拟器:几乎每个模拟步骤都是用户定义的。通过集成的脚本解释器可以实现这种灵活性。脚本语言是Lua,这是一种扩展编程语言,旨在支持常规过程编程。有关Lua的更多信息,请参阅Lua崩溃课程部分和在线文档。默认情况下,CoppeliaSim使用官方的和原始的Lua的,但如果你愿意,你可以告诉CoppeliaSim通过变量设置为使用Lua中的另一种风味useExternalLuaLibrary在系统/ usrset.txt至真。在这种情况下,所有Lua调用都通过simLua处理库,它本身将与LuaJIT(Lua即时编译器)链接。该simLua库项目文件都位于这里。有关Lua和LuaJIT的感谢和感谢,请参见此处。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGvVfJCQ-1595242154046)(https://www.coppeliarobotics.com/helpFiles/en/images/luaLogo.jpg)]
CoppeliaSim扩展了Lua的命令,并添加了可以由其sim前缀(例如sim.handleCollision)识别的CoppeliaSim特定命令。有关所有特定于CoppeliaSim的Lua命令的列表,请参阅常规API。也可以从主客户端应用程序或插件中注册新的自定义Lua命令。有关更多信息,请参考相关的API函数。
通过使用在线提供的Lua扩展库,可以轻松扩展Lua的功能本身。
嵌入式脚本是嵌入到场景(或模型)中的脚本,即,脚本是场景的一部分,并将与场景(或模型)的其余部分一起保存并加载。支持不同类型的嵌入式脚本。每种类型都有特定的功能和应用领域:
支持两种主要类型的嵌入式脚本:
模拟脚本:模拟脚本是仅在模拟期间执行的脚本,用于自定义模拟或模拟模型。主仿真循环通过主脚本处理,模型/机器人通过子脚本控制。
自定义脚本:这些脚本也可以在不运行模拟时执行,并用于自定义模拟场景或模拟器本身。
除了嵌入式脚本之外,CoppeliaSim还支持加载项和沙箱脚本,它们可提供未链接到特定场景或模型的特定功能。
在不同的脚本类型中,记住一些与场景对象(附加到场景对象,即关联的脚本)相关联的脚本可能很有用,例如子脚本,联合控制回调脚本和自定义脚本,而其他则与关联(即未关联的脚本) )。关联脚本构成CoppeliaSim分布式控制体系结构的基础,如果关联对象重复,它们共享的便利属性将自动复制。
CoppeliaSim脚本可以在任何许可下发布。
可以使用[菜单栏->模拟->开始/暂停/停止模拟]或通过相关的工具栏按钮来启动,暂停和停止CoppeliaSim中的模拟:
在内部,模拟器将使用其他中间状态,以正确告知脚本或程序接下来将发生的情况。以下状态图说明了模拟器的内部状态:
脚本和程序应始终根据当前的系统调用功能以及可能的模拟状态进行响应,以便正确运行。优良作法是将每个控制代码分成至少4个系统调用函数(例如,用于非线程子脚本):
有关如何安排典型脚本的示例,请参考main脚本,子脚本和自定义脚本页面。
仿真循环
模拟器通过以恒定的时间步长推进模拟时间来进行操作。下图说明了主要的仿真循环:
通过尝试使仿真时间与实时保持同步来支持实时仿真:
以下是一个非常简化的主客户端应用程序(为清晰起见,已省略了消息,插件处理和其他详细信息):
void initializeCallback
{
//在这里进行一些初始化
}
void loopCallback
{
if((simGetSimulationState()&sim_simulation_advancing)!= 0)
{
if(((simGetRealTimeSimulation()!= 1)!||(simIsRealTimeSimulationStepNeeded()== 1)))
{
if( (simHandleMainScript()&sim_script_main_script_not_drawn)== 0)
simAdvanceSimulationByOneStep();
}
}
}
void deinitializationCallback
{
//在此处进行一些清理
}
取决于仿真的复杂性,计算机的性能和仿真设置,实时仿真可能并不总是可能的。
仿真速度
在非实时仿真中,仿真速度(即感知的速度)主要取决于两个因素:仿真时间步长和一个渲染通道的仿真通道数量(有关更多详细信息,请参见仿真对话框)。在实时仿真的情况下,仿真速度主要取决于实时乘法系数,而且在一定程度上取决于仿真时间步长(太小的仿真时间步长可能与实时时间不兼容)。由于计算机的计算能力有限,因此无法进行仿真。在模拟过程中,可以使用以下工具栏按钮来调整模拟速度:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kPzbENeE-1595242154077)(https://www.coppeliarobotics.com/helpFiles/en/images/simulation5.jpg)]
以某种方式调整模拟速度,以使初始模拟时间步长永远不会增加(例如,这可能因此导致机制中断)。以下两个图说明了模拟速度调整机制:
默认情况下,每个模拟周期由以下顺序操作组成:
螺纹渲染
渲染操作将始终增加仿真周期的持续时间,从而也降低了仿真速度。可以定义每个场景渲染的主脚本执行次数(请参阅后面的内容),但这在某些情况下还不够,因为渲染仍然会减慢每个第x个模拟周期的时间(这可能会限制实时性)。在这种情况下,可以通过用户设置或以下工具栏按钮激活线程渲染模式:
激活线程渲染模式后,模拟周期将只包含执行主脚本的时间,因此模拟将以最大速度运行。渲染将通过不同的线程进行,并且不会减慢模拟任务的速度。然而,必须考虑缺点。激活线程渲染后,:
可以通过[菜单栏->模拟->模拟设置]或单击以下工具栏按钮来访问模拟对话框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cut1CKpu-1595242154097)(https://www.coppeliarobotics.com/helpFiles/en/images/simulationDialog2.jpg)]
CoppeliaSim具有嵌入式视频记录器,允许用户将页面,场景层次结构和模型浏览器区域记录为视频文件(单击此处和此处获取与视频记录功能相关的字幕)。不记录对话框,菜单栏,工具栏和弹出菜单。默认情况下,录像机将记录每个渲染的帧并生成每秒30帧的影片。请记住,根据所使用的编解码器,录制过程可能会大大降低模拟速度。可以使用[菜单栏->工具->录像机]或单击以下工具栏按钮来访问录像机对话框:
URDF文件格式(* .urdf)通过Ignacio Tartavull的插件coutesy:*simExtUrdf*支持导入操作。如果正确加载了URDF插件,则可以通过[菜单栏->插件-> URDF导入…]访问插件对话框:
通过插件*simExtSDF进行导入操作时,支持SDF文件格式( .sdf)。如果正确加载了SDF插件,则可以通过[菜单栏->插件-> SDF导入…]访问导入操作和对话框:
还支持以下API函数:
描述 | 检查SDF文件的结构。对跟踪错误很有用。 |
---|---|
Lua简介 | simSDF.dump(字符串fileName) |
Lua参数 | fileName:SDF文件路径 |
Lua返回值 | – |
描述 | 将SDF文件导入当前场景。 |
---|---|
Lua简介 | simSDF.import(string fileName,bool ignoreMissingValues = false,bool hideCollisionLinks = true,bool hideJoints = true,bool凸面分解= true,bool showConvexDecompositionDlg = false,bool createVisualIfNone = true,bool centerModel = true,bool prepareModel = true,bool noSelfCollision = true,布尔位置Ctrl = true) |
Lua参数 | 有关参数的详细信息,请参见上面的对话框 |
Lua返回值 | – |
通过插件simExtCollada支持导入/导出操作使用collada文件格式(* .dae)。当前,仅三角形/多边形网格被导入/导出。将来的版本还将支持读/写与物理相关的信息。如果collada插件已正确加载,则可以通过[插件-> COLLADA导入/导出…]访问插件对话框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ObM1F8lf-1595242154121)(https://www.coppeliarobotics.com/helpFiles/en/images/colladaPluginDlg.jpg)]
速成课程的内容是Lua官方参考手册的摘要。有关更多详细信息,请访问Lua网站以及演示场景中包含的众多示例。
词汇约定
Lua是区分大小写的语言。“and”,“And”或“AND”不相同。
以下是Lua关键字:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ]
; : , . .. ...
文字字符串可以通过匹配单引号或双引号来定界(例如,“ hello”或“ hello”)
注释在字符串之外的任何地方以双连字符(-)开头。例如:
a=4 -- 变量a现在是4!
值和类型
nil 类型的值nil,它的主要属性是不同于任何其他值。
它通常表示缺少有用的值
boolean 值false和true (nil和false都使条件为false;
任何其他值都会使其为true)
number 实数
string 字符数组(字符串可以包含任何8位字符,
包括嵌入式零)
function Lua 函数
userdata 可以保存任意的C数据(对应于一个原始内存块)
thread 用于实现协程的独立执行线程
table 可以保存除nil之外的任何类型的值的数组
变量
陈述
x,y,z = myTable[1],myTable[2],myTable[3]
== 相等
~= 不等
< 小于
> 大于
<= 小于或等于
>= 大于或等于
if value1==value2 then
print('value1 and value2 are same!')
end
for i=1,4,1 do -- 从1计数到4,以1为增量
print(i)
end
i=0
while i~=4 do
i=i+1
end
i=0
repeat
i=i+1
until i==4
myTable={'firstValue',2,3} -- 构建一个包含3个值的表
print(myTable[1]) -- 打印表中的第一个元素
table.insert(myTable,4) -- 将数字4追加到表中
a=' hello'
b=' world'
c=a..b -- c 包含了 'hello world'
stringLength=#'hello world'
tableSize=#{1,2,3,4,5}
CoppeliaSim支持两种不同的XML格式,每种格式都有不同的目标:
两种格式都有两个变量(在文件system / usrset.txt中定义),可以控制输出XML文件:
详尽的格式将不在此处进一步讨论。有关其他信息,请参考生成的文件。
简单的XML格式
简单格式(无论其名称如何)可以包含非常复杂的信息。每条信息都作为元素包装在开始标签和结束标签内。大多数标记是可选的(如果未指定,则将使用默认值)。全面了解此类文件的组织以及哪些标记不是可选的,最简单的方法是首先导出场景,然后检查/修改生成的文件。
下面基于简单的示例进行简要概述。首先,一个场景,其中包含连接到假人的相机。必填项以红色表示:
<CoppeliaSim>
<filetype>simpleScenefiletype> (Should be simpleScene or simpleModel)
<xmlSerializationNb>1xmlSerializationNb>
<environment> (ignored when loading a model)
... (refer to generated files for details)
environment>
<settings> (ignored when loading a model)
... (refer to generated files for details)
settings>
<dynamics> (ignored when loading a model)
... (refer to generated files for details)
dynamics>
<simulation> (ignored when loading a model)
... (refer to generated files for details)
simulation>
<dummy>
... (refer to generated files for details)
<camera>
... (refer to generated files for details)
camera>
dummy>
CoppeliaSim>
为场景对象指定更多标签是一个好主意,例如对象名称,相对于其父对象的位置/方向以及与之关联的脚本:
... <camera> <common> <name> DefaultCamera name> <localFrame> <position> 1.120530 -1.899800 1.079718 position> <euler> -110.932999 -28.703005 169.590027 euler> localFrame> ... (有关详细信息,请参阅生成的文件)
common>
<childScript> ... (有关详细信息,请参阅生成的文件) <scriptText> 函数sysCall_init() print('来自子脚本:Hello world!') end scriptText> childScript> <customizationScript> ... (请参阅到生成的文件以获取详细信息) <scriptText> ...
<camera>
<common>
<name>DefaultCameraname>
<localFrame>
<position>1.120530 -1.899800 1.079718position>
<euler>-110.932999 -28.703005 169.590027euler>
localFrame>
... (refer to generated files for details)
common>
<childScript>
... (refer to generated files for details)
<scriptText>
function sysCall_init()
print('From child script: Hello world!')
end
scriptText>
childScript>
<customizationScript>
... (refer to generated files for details)
<scriptText>
function sysCall_init()
print('From customization script: Hello world!')
end
scriptText>
customizationScript>
... (refer to generated files for details)
camera>
...() print('来自自定义脚本:Hello world!') 结束 scriptText> customizationScript> ... (请参阅生成的文件以获取详细信息)
camera> 。 ..
形状需要更多说明。这里是纯长方体,即原始形状:
<shape>
<common>
... (refer to generated files for details)
common>
<primitive> (should be compound, primitive, heightfield or mesh)
<type>cuboidtype> (should be cuboid, sphere, cylinder, cone, plane or disc)
<size>0.100000 0.100000 0.100000size>
<localFrame> (this is in addition to the local frame you may specify in <common>)
<position>0.000000 0.000000 0.000000position>
<euler>-0.000000 0.000000 -0.000000euler>
localFrame>
... (refer to generated files for details)
primitive>
<dynamics>
... (see further below for details)
dynamics>
shape>
这是一个引用外部文件的网格物体:
<shape>
<common>
... (refer to generated files for details)
common>
<mesh> (should be compound, primitive, heightfield or mesh)
<fileName>test.simscene_mesh_Cuboid0.daefileName> (or vertices and indices)
<localFrame> (this is in addition to the local frame you may specify in <common>)
<position>0.000000 0.000000 0.000000position>
<euler>-0.000000 0.000000 -0.000000euler>
localFrame>
... (refer to generated files for details)
mesh>
<dynamics>
... (see further below for details)
dynamics>
shape>
这里一个网,与内联网格数据:
<shape>
<common>
... (refer to generated files for details)
common>
<mesh> (should be compound, primitive, heightfield or mesh)
<vertices>0.05 -0.05 -0.05 -0.05 -0.05 -0.05 0.05 0.05 -0.05 -0.05 ...vertices>
<indices>0 1 2 2 1 3 1 0 4 1 4 5 2 3 6 6 3 7 6 7 4 4 7 5 3 1 7 7 1 5 0 2 6 0 6 4indices>
<localFrame> (this is in addition to the local frame you may specify in <common>)
<position>0.000000 0.000000 0.000000position>
<euler>-0.000000 0.000000 -0.000000euler>
localFrame>
... (refer to generated files for details)
mesh>
<dynamics>
... (see further below for details)
dynamics>
shape>
这是一个heightfield:
<shape>
<common>
... (refer to generated files for details)
common>
<heightfield> (should be compound, primitive, heightfield or mesh)
<size>4 3size>
<data>0.2 0.2 0.2 0.2 0.1 0.0 0.0 0.1 0.1 0.1 0.0 0.2data>
<gridStep>3.333333gridStep>
<localFrame> (this is in addition to the local frame you may specify in <common>)
<position>0.000000 0.000000 0.000000position>
<euler>-0.000000 0.000000 -0.000000euler>
localFrame>
... (refer to generated files for details)
heightfield>
<dynamics>
... (see further below for details)
dynamics>
shape>
这是一个化合物:
<shape>
<common>
... (refer to generated files for details)
common>
<compound> (should contain at least 2 of any of compound, primitive or mesh)
<primitive>
...
primitive>
<primitive>
...
primitive>
<compound>
...
compound>
...
compound>
<dynamics>
... (see further below for details)
dynamics>
shape>
如果形状具有动态属性,则还应填写dynamics标签,如以下示例所示:
<shape>
...
<dynamics>
<respondableMask>65535respondableMask>
<mass>1.0mass>
<localInertiaFrame>
<position>0.0 0.0 0.0position>
<euler>0.0 0.0 0.0euler>
localInertiaFrame>
<principalMomentOfInertia>0.001667 0.001667 0.001667principalMomentOfInertia>
<switches>
<static>falsestatic>
<respondable>truerespondable>
... (refer to generated files for details)
switches>
<material>
<engines>
<bullet>
<friction>0.5friction>
<oldfriction>1.0oldfriction>
... (refer to generated files for details)
bullet>
<ode>
<friction>1.0friction>
... (refer to generated files for details)
ode>
<vortex>
<primlinearaxisfriction>1.0primlinearaxisfriction>
<seclinearaxisfriction>1.0seclinearaxisfriction>
... (refer to generated files for details)
vortex>
<newton>
<staticfriction>1.0staticfriction>
<kineticfriction>1.0kineticfriction>
... (refer to generated files for details)
newton>
engines>
material>
dynamics>
shape>
这是IK模式下的旋转关节:
<joint>
<common>
... (refer to generated files for details)
common>
<type>revolutetype> (can be revolute, prismatic or spherical)
<mode>ikmode> (can be passive, ik, dependent or force)
<minPosition>-180.0minPosition>
<range>360.0range>
<position>0.0position>
<switches>
<cyclic>truecyclic>
<hybridMode>falsehybridMode>
switches>
... (refer to generated files for details)
joint>
这是在力/扭矩模式下禁用电机的旋转接头:
<joint>
<common>
... (refer to generated files for details)
common>
<type>revolutetype> (can be revolute, prismatic or spherical)
<mode>forcemode> (can be passive, ik, dependent or force)
<minPosition>-180.0minPosition>
<range>360.0range>
<position>0.0position>
<switches>
<cyclic>truecyclic>
<hybridMode>falsehybridMode>
switches>
<dynamics>
<maxForce>2.5maxForce>
... (refer to generated files for details)
<switches>
<motorEnabled>falsemotorEnabled>
... (refer to generated files for details)
switches>
<engines>
... (refer to generated files for details)
engines>
dynamics>
joint>
此处,在力/扭矩模式下的旋转关节位置受控:
<joint>
<common>
... (refer to generated files for details)
common>
<type>revolutetype> (can be revolute, prismatic or spherical)
<mode>forcemode> (can be passive, ik, dependent or force)
<minPosition>-180.0minPosition>
<range>360.0range>
<position>0.0position>
<switches>
<cyclic>truecyclic>
<hybridMode>falsehybridMode>
switches>
<dynamics>
<maxForce>2.5maxForce>
<upperVelocityLimit>180upperVelocityLimit>
<targetPosition>0.0targetPosition>
<pidValues>0.1 0.0 0.0pidValues>
... (refer to generated files for details)
<switches>
<motorEnabled>falsemotorEnabled>
<controlLoopEnabled>truecontrolLoopEnabled>
... (refer to generated files for details)
switches>
<engines>
... (refer to generated files for details)
engines>
dynamics>
joint>
其他场景对象不在此处讨论。有关详细信息,请导出包含此类对象的场景,然后检查生成的文件。
这里的简化版本BubbleRob,从本教程:
<CoppeliaSim>
<filetype>simpleScenefiletype>
<xmlSerializationNb>1xmlSerializationNb>
<shape>
<common>
<name>wallsname>
<localFrame>
<position>0 0 0.1position>
<euler>0 -90 0euler>
localFrame>
<localObjectProperty>
<selectable>falseselectable>
localObjectProperty>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<compound>
<primitive>
<type>cuboidtype>
<size>5 0.02 0.2size>
<localFrame>
<position>0 2.5 0position>
<euler>0 90 0euler>
localFrame>
primitive>
<primitive>
<type>cuboidtype>
<size>5 0.02 0.2size>
<localFrame>
<position>0 0 -2.5position>
<euler>0 90 90euler>
localFrame>
primitive>
<primitive>
<type>cuboidtype>
<size>5 0.02 0.2size>
<localFrame>
<position>0 0 2.5position>
<euler>0 90 90euler>
localFrame>
primitive>
<primitive>
<type>cuboidtype>
<size>5 0.02 0.2size>
<localFrame>
<position>0 -2.5 0position>
<euler>0 90 0euler>
localFrame>
primitive>
compound>
<dynamics>
<switches>
<static>truestatic>
<respondable>truerespondable>
switches>
dynamics>
shape>
<shape>
<common>
<name>obstaclename>
<localFrame>
<position>1 0 0.1position>
localFrame>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<primitive>
<type>cuboidtype>
<size>0.2 0.2 0.2size>
primitive>
<dynamics>
<switches>
<static>truestatic>
<respondable>truerespondable>
switches>
dynamics>
shape>
<light>
<common>
<name>lightname>
<localFrame>
<position>0 0 2position>
<euler>100 -50 0euler>
localFrame>
common>
<type>directionaltype>
<color>
<light>
<ambientDiffuse>127 127 127ambientDiffuse>
light>
color>
light>
<shape>
<common>
<name>bubbleRobname>
<localFrame>
<position>0 0 0.12position>
localFrame>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
<switches>
<modelBase>truemodelBase>
switches>
common>
<primitive>
<type>spheretype>
<size>0.2 0.2 0.2size>
<color>
<ambientDiffuse>255 167 36ambientDiffuse>
color>
primitive>
<dynamics>
<respondableMask>65295respondableMask>
<mass>4mass>
<principalMomentOfInertia>0.004 0.004 0.004principalMomentOfInertia>
<switches>
<static>falsestatic>
<respondable>truerespondable>
switches>
dynamics>
<childScript>
<switches>
<threadedExecution>falsethreadedExecution>
switches>
<scriptText>function sysCall_init()
leftMotor=sim.getObjectHandle('bubbleRobLeftMotor')
rightMotor=sim.getObjectHandle('bubbleRobRightMotor')
noseSensor=sim.getObjectHandle('bubbleRobSensingNose')
driveBackTime=0
end
function sysCall_actuation()
if driveBackTime>0 then
driveBackTime=driveBackTime-sim.getSimulationTimeStep()
end
local result=sim.readProximitySensor(noseSensor)
if result>0 then
driveBackTime=3
sim.setJointTargetVelocity(leftMotor,-math.pi*0.5)
sim.setJointTargetVelocity(rightMotor,-math.pi*0.25)
end
if driveBackTime<=0 then
sim.setJointTargetVelocity(leftMotor,math.pi)
sim.setJointTargetVelocity(rightMotor,math.pi)
end
endscriptText>
childScript>
<proximitySensor>
<common>
<name>bubbleRobSensingNosename>
<localFrame>
<position>0.1 0 0position>
<euler>0 90 90euler>
localFrame>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
common>
<type>conetype>
<size>0.01size>
<volume>
<range>0.15range>
<smallestAllowedDistance>0.01smallestAllowedDistance>
<angle>60angle>
volume>
proximitySensor>
<joint>
<common>
<name>bubbleRobLeftMotorname>
<localFrame>
<position>0.05 0.1 -0.08position>
<euler>-90 0 0euler>
localFrame>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
common>
<type>revolutetype>
<mode>forcemode>
<switches>
<cyclic>truecyclic>
switches>
<sizes>
<length>0.15length>
<diameter>0.02diameter>
sizes>
<dynamics>
<maxForce>2.5maxForce>
<upperVelocityLimit>360upperVelocityLimit>
<switches>
<motorEnabled>truemotorEnabled>
switches>
dynamics>
<shape>
<common>
<name>bubbleRobLeftWheelname>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<primitive>
<type>cylindertype>
<size>0.08 0.08 0.02size>
<color>
<ambientDiffuse>64 64 64ambientDiffuse>
color>
primitive>
<dynamics>
<mass>0.8mass>
<principalMomentOfInertia>0.0004 0.0004 0.0008principalMomentOfInertia>
<switches>
<static>falsestatic>
<respondable>truerespondable>
switches>
dynamics>
shape>
joint>
<joint>
<common>
<name>bubbleRobRightMotorname>
<localFrame>
<position>0.05 -0.1 -0.08position>
<euler>-90 0 0euler>
localFrame>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
common>
<type>revolutetype>
<mode>forcemode>
<switches>
<cyclic>truecyclic>
switches>
<sizes>
<length>0.15length>
<diameter>0.02diameter>
sizes>
<dynamics>
<maxForce>2.5maxForce>
<upperVelocityLimit>360upperVelocityLimit>
<switches>
<motorEnabled>truemotorEnabled>
switches>
dynamics>
<shape>
<common>
<name>bubbleRobRightWheelname>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<primitive>
<type>cylindertype>
<size>0.08 0.08 0.02size>
<color>
<ambientDiffuse>64 64 64ambientDiffuse>
color>
primitive>
<dynamics>
<mass>0.8mass>
<principalMomentOfInertia>0.0004 0.0004 0.0008principalMomentOfInertia>
<switches>
<static>falsestatic>
<respondable>truerespondable>
switches>
dynamics>
shape>
joint>
<forceSensor>
<common>
<name>bubbleRobLinkname>
<localFrame>
<position>-0.07 0 -0.07position>
localFrame>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
common>
<size>0.05size>
<shape>
<common>
<name>bubbleRobCastername>
<localFrame>
<position>0 0 -0.025position>
localFrame>
<localObjectProperty>
<selectModelBaseInstead>trueselectModelBaseInstead>
localObjectProperty>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<primitive>
<type>spheretype>
<size>0.05 0.05 0.05size>
<color>
<ambientDiffuse>55 55 55ambientDiffuse>
color>
primitive>
<dynamics>
<respondableMask>65520respondableMask>
<mass>0.5mass>
<principalMomentOfInertia>0.00025 0.00025 0.00025principalMomentOfInertia>
<switches>
<static>falsestatic>
<respondable>truerespondable>
switches>
<material>
<engines>
<bullet>
<friction>0friction>
bullet>
<ode>
<friction>0friction>
ode>
<vortex>
<primlinearaxisfriction>0primlinearaxisfriction>
<seclinearaxisfriction>0seclinearaxisfriction>
vortex>
<newton>
<staticfriction>0staticfriction>
<kineticfriction>0kineticfriction>
newton>
engines>
material>
dynamics>
shape>
forceSensor>
shape>
<camera>
<common>
<name>cameraname>
<localFrame>
<position>0.952512 1.344827 0.718737position>
<euler>114.251228 -20.888456 9.124518euler>
localFrame>
common>
<mainCamera>truemainCamera>
camera>
<shape>
<common>
<name>floorname>
<localFrame>
<position>0 0 -0.02position>
localFrame>
<localObjectProperty>
<selectable>falseselectable>
localObjectProperty>
<localObjectSpecialProperty>
<collidable>truecollidable>
<measurable>truemeasurable>
<renderable>truerenderable>
<detectable>truedetectable>
localObjectSpecialProperty>
common>
<primitive>
<type>cuboidtype>
<size>5 5 0.04size>
<color>
<ambientDiffuse>209 209 209ambientDiffuse>
color>
primitive>
<dynamics>
<switches>
<static>truestatic>
<respondable>truerespondable>
switches>
dynamics>
shape>
CoppeliaSim>
PDF格式下载链接
提取码:4de4