XML formats
CoppeliaSim supports two different XML formats, where each follow a different goal:
an exhaustive format: the exhaustive format is a lossless format, which means that all scene or model information will be same between a save and load operation. The drawback is however that the file should not be manually modified, since the risk of corrupting it is high. This format is ideal for version control for example.
a simple format: the simple format is a lossy format, which means that not all information contained in a scene or model will be saved, only a subset of it. The advantage is however that it can be manually created and/or modified. This format is ideal for creating initial models, or for creating CoppeliaSim exporters in different applications.
Both formats have two variables (defined in file system/usrset.txt) allowing to control the output XML file:
xmlExportSplitSize: represents the subset data size threshold where data will be referenced and written to a separate file. Set to 0 if you wish to create a single file.
xmlExportKnownFormats: if true, and the export generates several files, then the png format for images, and the dae format for meshs are used. The dae format is however only supported with the simple xml format.
The exhaustive format will not be discussed further here. Refer to the generated files for additional information.
Simple XML format
The simple format, however its name, can contain quite complex information. Each piece of information is wrapped as element inside of a start- and end-tag. Most tags are optional (if not specified, then default values will be used). The simplest to get a good understanding of such a file's organization and which tags are not optional is to first export a scene, then examine/modify the generated file.
Following gives a brief overview, based on simple examples. First, a scene containing a camera attached to a dummy. Required items are indicated in red:
<CoppeliaSim>
<filetype>simpleScene</filetype> (Should be simpleScene or simpleModel)
<xmlSerializationNb>1</xmlSerializationNb>
<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>
It is a good idea to specify a few more tags for a scene object, such as the object alias, its position/orientation relative to its parent object, and the script(s) it is associated with:
... <camera> <common> <alias>DefaultCamera</alias> <localFrame> <position>1.120530 -1.899800 1.079718</position> <euler>-110.932999 -28.703005 169.590027</euler> </localFrame> ... (refer to generated files for details)
</common>
<childScript> ... (refer to generated files for details) <scriptText><![CDATA[ function sysCall_init() print('From child script: Hello world!') end ]]></scriptText> </childScript> <customizationScript> ... (refer to generated files for details) <scriptText><![CDATA[ function sysCall_init() print('From customization script: Hello world!') end ]]></scriptText> </customizationScript> ... (refer to generated files for details)
</camera> ...
Shapes require a bit more explanations. Here a pure cuboid, i.e. a primitive shape:
<shape> <common> ... (refer to generated files for details)
</common> <primitive> (should be compound, primitive, heightfield or mesh) <type>cuboid</type> (should be cuboid, sphere, cylinder, cone, plane or disc) <size>0.100000 0.100000 0.100000</size>
<localFrame> (this is in addition to the local frame you may specify in <common>) <position>0.000000 0.000000 0.000000</position> <euler>-0.000000 0.000000 -0.000000</euler> </localFrame>
... (refer to generated files for details)
</primitive> <dynamics> ... (see further below for details)
</dynamics> </shape>
Here a mesh, referencing an external file:
<shape> <common> ... (refer to generated files for details)
</common> <mesh> (should be compound, primitive, heightfield or mesh) <fileName>test.simscene_mesh_Cuboid0.dae</fileName> (or vertices and indices)
<localFrame> (this is in addition to the local frame you may specify in <common>) <position>0.000000 0.000000 0.000000</position> <euler>-0.000000 0.000000 -0.000000</euler> </localFrame>
... (refer to generated files for details)
</mesh> <dynamics> ... (see further below for details)
</dynamics> </shape>
Here a mesh, with inlined mesh data:
<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 4</indices>
<localFrame> (this is in addition to the local frame you may specify in <common>) <position>0.000000 0.000000 0.000000</position> <euler>-0.000000 0.000000 -0.000000</euler> </localFrame>
... (refer to generated files for details)
</mesh> <dynamics> ... (see further below for details)
</dynamics> </shape>
Here a heightfield:
<shape> <common> ... (refer to generated files for details)
</common> <heightfield> (should be compound, primitive, heightfield or mesh)
<size>4 3</size>
<data>0.2 0.2 0.2 0.2 0.1 0.0 0.0 0.1 0.1 0.1 0.0 0.2</data>
<gridStep>3.333333</gridStep>
<localFrame> (this is in addition to the local frame you may specify in <common>) <position>0.000000 0.000000 0.000000</position> <euler>-0.000000 0.000000 -0.000000</euler> </localFrame>
... (refer to generated files for details)
</heightfield> <dynamics> ... (see further below for details)
</dynamics> </shape>
And here a compound:
<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>
If a shape has dynamic properties, you should also fill-in the dynamics tags, as in following example:
<shape> ... <dynamics> <respondableMask>65535</respondableMask> <mass>1.0</mass> <localInertiaFrame> <position>0.0 0.0 0.0</position> <euler>0.0 0.0 0.0</euler> </localInertiaFrame> <principalMomentOfInertia>0.001667 0.001667 0.001667</principalMomentOfInertia> <switches> <static>false</static> <respondable>true</respondable> ... (refer to generated files for details) </switches> <material> <engines> <bullet> <friction>0.5</friction> <oldfriction>1.0</oldfriction> ... (refer to generated files for details) </bullet> <ode> <friction>1.0</friction> ... (refer to generated files for details) </ode> <vortex> <primlinearaxisfriction>1.0</primlinearaxisfriction> <seclinearaxisfriction>1.0</seclinearaxisfriction> ... (refer to generated files for details) </vortex> <newton> <staticfriction>1.0</staticfriction> <kineticfriction>1.0</kineticfriction> ... (refer to generated files for details) </newton> </engines> </material> </dynamics> </shape>
Here a revolute joint, in kinematic mode:
<joint> <common> ... (refer to generated files for details) </common> <type>revolute</type> (can be revolute, prismatic or spherical) <mode>kinematic</mode> (can be kinematic, dependent or dynamic) <minPosition>-180.0</minPosition> <range>360.0</range> <position>0.0</position> <switches> <cyclic>true</cyclic> </switches> ... (refer to generated files for details) </joint>
Here a revolute joint, in dynamic mode, motor disabled:
<joint> <common> ... (refer to generated files for details) </common> <type>revolute</type> (can be revolute, prismatic or spherical) <mode>dynamic</mode> (can be kinematic, dependent or dynamic) <minPosition>-180.0</minPosition> <range>360.0</range> <position>0.0</position> <switches> <cyclic>true</cyclic> </switches>
<dynamics> <maxForce>2.5</maxForce> ... (refer to generated files for details) <switches> <motorEnabled>false</motorEnabled> ... (refer to generated files for details) </switches> <engines> ... (refer to generated files for details) </engines> </dynamics> </joint>
Here a revolute joint, in dynamic mode, position controlled:
<joint> <common> ... (refer to generated files for details) </common> <type>revolute</type> (can be revolute, prismatic or spherical) <mode>dynamic</mode> (can be kinematic, dependent or dynamic) <minPosition>-180.0</minPosition> <range>360.0</range> <position>0.0</position> <switches> <cyclic>true</cyclic> </switches>
<dynamics> <maxForce>2.5</maxForce> <upperVelocityLimit>180</upperVelocityLimit> <targetPosition>0.0</targetPosition> <pidValues>0.1 0.0 0.0</pidValues> ... (refer to generated files for details) <switches> <motorEnabled>false</motorEnabled> <controlLoopEnabled>true</controlLoopEnabled> ... (refer to generated files for details) </switches> <engines> ... (refer to generated files for details) </engines> </dynamics> </joint>
Other scene objects are not discussed here. For details, export a scene containing such object, then examine the generated file.
Here a simplified version of BubbleRob, from this tutorial:
<CoppeliaSim> <filetype>simpleScene</filetype> <xmlSerializationNb>1</xmlSerializationNb> <shape> <common> <alias>walls</alias> <localFrame> <position>0 0 0.1</position> <euler>0 -90 0</euler> </localFrame> <localObjectProperty> <selectable>false</selectable> </localObjectProperty> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <compound> <primitive> <type>cuboid</type> <size>5 0.02 0.2</size> <localFrame> <position>0 2.5 0</position> <euler>0 90 0</euler> </localFrame> </primitive> <primitive> <type>cuboid</type> <size>5 0.02 0.2</size> <localFrame> <position>0 0 -2.5</position> <euler>0 90 90</euler> </localFrame> </primitive> <primitive> <type>cuboid</type> <size>5 0.02 0.2</size> <localFrame> <position>0 0 2.5</position> <euler>0 90 90</euler> </localFrame> </primitive> <primitive> <type>cuboid</type> <size>5 0.02 0.2</size> <localFrame> <position>0 -2.5 0</position> <euler>0 90 0</euler> </localFrame> </primitive> </compound> <dynamics> <switches> <static>true</static> <respondable>true</respondable> </switches> </dynamics> </shape> <shape> <common> <alias>obstacle</alias> <localFrame> <position>1 0 0.1</position> </localFrame> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <primitive> <type>cuboid</type> <size>0.2 0.2 0.2</size> </primitive> <dynamics> <switches> <static>true</static> <respondable>true</respondable> </switches> </dynamics> </shape> <light> <common> <alias>light</alias> <localFrame> <position>0 0 2</position> <euler>100 -50 0</euler> </localFrame> </common> <type>directional</type> <color> <light> <ambientDiffuse>127 127 127</ambientDiffuse> </light> </color> </light> <shape> <common> <alias>bubbleRob</alias> <localFrame> <position>0 0 0.12</position> </localFrame> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> <switches> <modelBase>true</modelBase> </switches> </common> <primitive> <type>sphere</type> <size>0.2 0.2 0.2</size> <color> <ambientDiffuse>255 167 36</ambientDiffuse> </color> </primitive> <dynamics> <respondableMask>65295</respondableMask> <mass>4</mass> <principalMomentOfInertia>0.004 0.004 0.004</principalMomentOfInertia> <switches> <static>false</static> <respondable>true</respondable> </switches> </dynamics> <childScript> <scriptText><![CDATA[
function sysCall_init() leftMotor=sim.getObject('./bubbleRobLeftMotor') rightMotor=sim.getObject('./bubbleRobRightMotor') noseSensor=sim.getObject('./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 end
]]></scriptText> </childScript> <proximitySensor> <common> <alias>bubbleRobSensingNose</alias> <localFrame> <position>0.1 0 0</position> <euler>0 90 90</euler> </localFrame> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> </common> <type>cone</type> <size>0.01</size> <volume> <range>0.15</range> <smallestAllowedDistance>0.01</smallestAllowedDistance> <angle>60</angle> </volume> </proximitySensor> <joint> <common> <alias>bubbleRobLeftMotor</alias> <localFrame> <position>0.05 0.1 -0.08</position> <euler>-90 0 0</euler> </localFrame> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> </common> <type>revolute</type> <mode>force</mode> <switches> <cyclic>true</cyclic> </switches> <sizes> <length>0.15</length> <diameter>0.02</diameter> </sizes> <dynamics> <maxForce>2.5</maxForce> <upperVelocityLimit>360</upperVelocityLimit> <switches> <motorEnabled>true</motorEnabled> </switches> </dynamics> <shape> <common> <alias>bubbleRobLeftWheel</alias> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <primitive> <type>cylinder</type> <size>0.08 0.08 0.02</size> <color> <ambientDiffuse>64 64 64</ambientDiffuse> </color> </primitive> <dynamics> <mass>0.8</mass> <principalMomentOfInertia>0.0004 0.0004 0.0008</principalMomentOfInertia> <switches> <static>false</static> <respondable>true</respondable> </switches> </dynamics> </shape> </joint> <joint> <common> <alias>bubbleRobRightMotor</alias> <localFrame> <position>0.05 -0.1 -0.08</position> <euler>-90 0 0</euler> </localFrame> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> </common> <type>revolute</type> <mode>force</mode> <switches> <cyclic>true</cyclic> </switches> <sizes> <length>0.15</length> <diameter>0.02</diameter> </sizes> <dynamics> <maxForce>2.5</maxForce> <upperVelocityLimit>360</upperVelocityLimit> <switches> <motorEnabled>true</motorEnabled> </switches> </dynamics> <shape> <common> <alias>bubbleRobRightWheel</alias> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <primitive> <type>cylinder</type> <size>0.08 0.08 0.02</size> <color> <ambientDiffuse>64 64 64</ambientDiffuse> </color> </primitive> <dynamics> <mass>0.8</mass> <principalMomentOfInertia>0.0004 0.0004 0.0008</principalMomentOfInertia> <switches> <static>false</static> <respondable>true</respondable> </switches> </dynamics> </shape> </joint> <forceSensor> <common> <alias>bubbleRobLink</alias> <localFrame> <position>-0.07 0 -0.07</position> </localFrame> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> </common> <size>0.05</size> <shape> <common> <alias>bubbleRobCaster</alias> <localFrame> <position>0 0 -0.025</position> </localFrame> <localObjectProperty> <selectModelBaseInstead>true</selectModelBaseInstead> </localObjectProperty> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <primitive> <type>sphere</type> <size>0.05 0.05 0.05</size> <color> <ambientDiffuse>55 55 55</ambientDiffuse> </color> </primitive> <dynamics> <respondableMask>65520</respondableMask> <mass>0.5</mass> <principalMomentOfInertia>0.00025 0.00025 0.00025</principalMomentOfInertia> <switches> <static>false</static> <respondable>true</respondable> </switches> <material> <engines> <bullet> <friction>0</friction> </bullet> <ode> <friction>0</friction> </ode> <vortex> <primlinearaxisfriction>0</primlinearaxisfriction> <seclinearaxisfriction>0</seclinearaxisfriction> </vortex> <newton> <staticfriction>0</staticfriction> <kineticfriction>0</kineticfriction> </newton> </engines> </material> </dynamics> </shape> </forceSensor> </shape> <camera> <common> <alias>camera</alias> <localFrame> <position>0.952512 1.344827 0.718737</position> <euler>114.251228 -20.888456 9.124518</euler> </localFrame> </common> <mainCamera>true</mainCamera> </camera> <shape> <common> <alias>floor</alias> <localFrame> <position>0 0 -0.02</position> </localFrame> <localObjectProperty> <selectable>false</selectable> </localObjectProperty> <localObjectSpecialProperty> <collidable>true</collidable> <measurable>true</measurable> <detectable>true</detectable> </localObjectSpecialProperty> </common> <primitive> <type>cuboid</type> <size>5 5 0.04</size> <color> <ambientDiffuse>209 209 209</ambientDiffuse> </color> </primitive> <dynamics> <switches> <static>true</static> <respondable>true</respondable> </switches> </dynamics> </shape> </CoppeliaSim>
|