diff --git a/batch_conversion.py b/batch_conversion.py
new file mode 100755
index 00000000..913c6cd8
--- /dev/null
+++ b/batch_conversion.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python3
+
+"""URDF files to Webots PROTO batch-converter.
+------------------------------------------------------------------------
+This script searches for all urdf files in the directory, converts
+them to proto files and saves them in the output directory. It retains
+the folder structure of the input directory while doing so.
+
+The first time a urdf file gets converted, this script creates a config
+.json file next to it. Here you can specify any arguments you want
+to parse to that specific file conversion. The definiton of the default
+config is in the code below and needs to be updated when features get added.
+
+For each batch-conversion, a new (unique) folder is generated inside the
+output folder, where the conversion is being placed in. This way, previous
+conversions are not overridden. In addition, the converted files override
+those in '/ExtraProjectTest' and the TestAllRobots.wbt world is
+created and placed there, containing all converted models, placed in a grid.
+
+To test the conversions, open webots and change your
+Tools>Prefernces>Extra_projects_path to '/ExtraProjectTest' and
+open the generated TestAllRobots.wbt. From now on, after another conversion,
+you simply have to reload the world.
+
+Example:
+ /robots/kuka/protos/kr5.urdf
+gets exportet to
+'//robots/kuka/protos/kr5.proto'
+and
+'/ExtraProjectTest/robots/kuka/protos/kr5.proto'
+
+Note: Webots will only automatically find your proto file, if it is inside a
+'protos' folder.
+"""
+
+import optparse
+import datetime
+import os
+import shutil
+import json
+import math
+# from urdf2webots.importer import convert2urdf
+import urdf2webots.importer as importer
+from copy import deepcopy
+
+# Set Override = True if you want to override ALL config settings with the
+# value in the OverrideCfg. This can be usefull for testing functionality
+# quickly, and then doing a slow optimized conversion
+Override = False
+OverrideCfg = {
+ 'disableMeshOptimization': False
+}
+
+# This defines the default config. If a urdf model doesnt have a config, one
+# will created after this. If the importer.py is updated, so should this to
+# add the additional functionality-
+default_config = {
+ # outFile will get constructed with protosPath + robotName + '.proto'
+ 'robotName': None,
+ 'normal': False,
+ 'boxCollision': True,
+ 'disableMeshOptimization': True,
+ 'enableMultiFile': True,
+ 'staticBase': True,
+ 'toolSlot': None,
+ 'initRotation': "1 0 0 -1.5708"
+}
+
+
+class BatchConversion():
+ def __init__(self, sourcePath, outPath):
+ self.urdf2webots_path = os.path.dirname(os.path.abspath(__file__))
+ # create a unique path for a new batch-conversion
+ today = datetime.date.today()
+ todaystr = today.isoformat()
+ self.protoTargetDir = outPath + '/protos_' + todaystr
+ n = 2
+ while os.path.exists(self.protoTargetDir):
+ while os.path.exists(self.protoTargetDir + '_Nr-' + str(n)):
+ n += 1
+ self.protoTargetDir = self.protoTargetDir + '_Nr-' + str(n)
+
+ # Find all the urdf files, and create the corresponding proto filePaths
+ urdf_root_dir = sourcePath
+ os.chdir(urdf_root_dir)
+ # Walk the tree.
+ self.urdf_files = [] # List of the full filepaths.
+ self.protosPaths = []
+ for root, directories, files in os.walk('./'):
+ for filename in files:
+ # Join the two strings in order to form the full filepath.
+ if filename.endswith(".urdf"):
+ filepath = os.path.join(root, filename)
+ filepath = filepath[1:]
+ self.urdf_files.append(urdf_root_dir + filepath)
+ self.protosPaths.append(self.protoTargetDir + os.path.dirname(filepath) + '/')
+ os.chdir(self.urdf2webots_path)
+
+ # Report dict we can print at the end
+ self.EndReportMessage = {
+ 'updateConfigs': [],
+ 'newConfigs': [],
+ 'converted': [],
+ 'failed': []
+ }
+
+ def update_and_convert(self):
+ """Make sure all configs exist and are up to date, then convert all URDF files."""
+ self.check_all_configs()
+ self.convert_all_urdfs()
+ self.print_end_report()
+
+ def create_proto_dir(self):
+ """Create a new unique directory for our conversions."""
+ print(self.protoTargetDir)
+ os.makedirs(self.protoTargetDir)
+
+ def replace_ExtraProjectPath(self):
+ # this copies the converted files and puts them in the "/ExtraProjectTest" directory
+ # This path can be added to webots, so we can test each new conversion, without having to adjust the Path
+ # every time
+ destination = os.path.dirname(self.protoTargetDir) + '/ExtraProjectTest'
+ if os.path.isfile(destination) or os.path.islink(destination):
+ os.remove(destination) # remove the file
+ elif os.path.isdir(destination):
+ shutil.rmtree(destination) # remove dir and all contains
+ shutil.copytree(self.protoTargetDir, destination)
+
+ def update_config(self, configFile, config=None):
+ """Makes sure the existing configs are in the same format as the default, existing options are conserved."""
+ new_config = deepcopy(default_config)
+ for key in new_config.keys():
+ try:
+ new_config[key] = config[key]
+ except:
+ pass
+ with open(configFile, 'w') as outfile:
+ json.dump(new_config, outfile, indent=4, sort_keys=True)
+
+ def check_all_configs(self):
+ """Makes sure ever URDF file has a config and it is up to date."""
+ print('Checking config files...')
+ print('---------------------------------------')
+ for i in range(len(self.urdf_files)):
+ configFile = os.path.splitext(self.urdf_files[i])[0] + '.json'
+ try:
+ with open(configFile) as json_file:
+ config = json.load(json_file)
+ if config.keys() != default_config.keys():
+ print('Updating config (old settings will be carried over) - ', configFile)
+ self.EndReportMessage['updateConfigs'].append(configFile)
+ self.update_config(configFile, config)
+ else:
+ print('Config up to date - ', configFile)
+ except:
+ print('Generating new config for - ' + os.path.splitext(self.urdf_files[i])[0])
+ self.EndReportMessage['newConfigs'].append(configFile)
+ self.update_config(configFile)
+
+ def convert_all_urdfs(self):
+ """Converts all URDF files according to their '.json' config files."""
+ self.create_proto_dir()
+ print('---------------------------------------')
+ print('Converting URDF to PROTO...')
+ print('---------------------------------------')
+ print('---------------------------------------')
+ for i in range(len(self.urdf_files)):
+ # clears any previous Geometry and Material references, so there is no conflict
+ importer.urdf2webots.parserURDF.Geometry.reference = {}
+ importer.urdf2webots.parserURDF.Material.namedMaterial = {}
+ configFile = os.path.splitext(self.urdf_files[i])[0] + '.json'
+ print('---------------------------------------')
+ print('Converting: ', self.urdf_files[i])
+ print('---------------------------------------')
+ try:
+ with open(configFile) as json_file:
+ config = json.load(json_file)
+ importer.convert2urdf(
+ inFile=self.urdf_files[i],
+ outFile=self.protosPaths[i] if not config['robotName'] else self.protosPaths[i] + config['robotName'] + '.proto',
+ normal=config['normal'],
+ boxCollision=config['boxCollision'],
+ disableMeshOptimization=OverrideCfg['disableMeshOptimization'] if Override else config['disableMeshOptimization'],
+ enableMultiFile=config['enableMultiFile'],
+ staticBase=config['staticBase'],
+ toolSlot=config['toolSlot'],
+ initRotation=config['initRotation'])
+ self.EndReportMessage['converted'].append(self.urdf_files[i])
+ except Exception as e:
+ print(e)
+ self.EndReportMessage['failed'].append(self.urdf_files[i])
+ print('---------------------------------------')
+
+ def print_end_report(self):
+ """Print the report."""
+ print('---------------------------------------')
+ print('------------End Report-----------------')
+ print('---------------------------------------')
+ print('Configs updated:')
+ print('---------------------------------------')
+ for config in self.EndReportMessage['updateConfigs']:
+ print(config)
+ print('---------------------------------------')
+ print('Configs created:')
+ print('---------------------------------------')
+ for config in self.EndReportMessage['newConfigs']:
+ print(config)
+ print('---------------------------------------')
+ print('Successfully converted URDF files:')
+ print('---------------------------------------')
+ for urdf in self.EndReportMessage['converted']:
+ print(urdf)
+ if len(self.EndReportMessage['failed']) > 0:
+ print('---------------------------------------')
+ print('Failedd URDF conversions:')
+ print('---------------------------------------')
+ for urdf in self.EndReportMessage['failed']:
+ print(urdf)
+
+ def create_test_world(self, spacing=3):
+ '''Create a TestWorld (/ExtraProjectTest/TestAllRobots.wbt')
+ where every converted robot or model is placed in a grid, with the
+ spacing representing the grid size'''
+ n_models = len(self.urdf_files)
+ n_row = math.ceil(n_models ** 0.5) # round up the sqrt of the number of models
+ grid_size = spacing * (n_row + 1)
+ projectDir = os.path.dirname(self.protoTargetDir) + '/ExtraProjectTest/TestAllRobots.wbt'
+ worldFile = open(projectDir, 'w')
+ worldFile.write('#VRML_SIM R2020b utf8\n')
+ worldFile.write('\n')
+ worldFile.write('WorldInfo {\n')
+ worldFile.write(' basicTimeStep 16\n')
+ worldFile.write(' coordinateSystem "NUE"\n')
+ worldFile.write('}\n')
+ worldFile.write('Viewpoint {\n')
+ worldFile.write(' orientation 0.7180951961816571 -0.6372947429425837 -0.27963315225232777 5.235063704863283\n')
+ worldFile.write(' position 1.9410928989638234 2.447392518518642 1.7311802992777219\n')
+ worldFile.write('}\n')
+ worldFile.write('TexturedBackground {\n')
+ worldFile.write('}\n')
+ worldFile.write('TexturedBackgroundLight {\n')
+ worldFile.write('}\n')
+ worldFile.write('RectangleArena {\n')
+ worldFile.write(' floorSize ' + str(grid_size) + ' ' + str(grid_size) + '\n')
+ worldFile.write(' floorTileSize 0.25 0.25\n')
+ worldFile.write(' wallHeight 0.05\n')
+ worldFile.write('}\n')
+ row = 0
+ column = 1
+ for root, directories, files in os.walk(os.path.dirname(projectDir)):
+ for filename in files:
+ # Join the two strings in order to form the full filepath.
+ if filename.endswith(".proto"):
+ filepath = os.path.join(root, filename)
+ if os.path.dirname(filepath).split('_')[-1] != 'meshes':
+ name = os.path.splitext(os.path.basename(filename))[0]
+ if row == n_row:
+ column += 1
+ row = 0
+ row += 1
+ # add the model to the world file with translation to be spaced in a grid
+ worldFile.write(name + ' {\n')
+ worldFile.write(' translation ' + str(column * spacing - grid_size / 2) + ' 0 ' + str(row * spacing - grid_size / 2) + '\n')
+ worldFile.write('}\n')
+ worldFile.close()
+ os.chdir(self.urdf2webots_path)
+
+
+if __name__ == '__main__':
+ optParser = optparse.OptionParser(usage='usage: %prog [options]')
+ optParser.add_option('--input', dest='sourcePath', default='', help='Specifies the urdf file to convert.')
+ optParser.add_option('--output', dest='outPath', default='', help='Specifies the path and, if ending in ".proto", name of the resulting PROTO file.'
+ ' The filename minus the .proto extension will be the robot name.')
+ optParser.add_option('--force-mesh-optimization', dest='forceMesh', action='store_true', default=False, help='Set if mesh-optimization should be turned on for all conversions. This will take much longer!')
+ optParser.add_option('--no-project-override', dest='extraProj', action='store_true', default=False, help='Set if new conversions should NOT replace existing ones in " /ExtraProjectTest".')
+ optParser.add_option('--update-cfg', dest='cfgUpdate', action='store_true', default=False, help='No conversion. Only updates or creates .json config for every URDF file in "automatic_conversion/urdf".')
+
+ options, args = optParser.parse_args()
+ bc = BatchConversion(options.sourcePath, options.outPath)
+ Override = options.forceMesh
+ if options.cfgUpdate:
+ bc.check_all_configs()
+ else:
+ bc.update_and_convert()
+ if not options.extraProj:
+ bc.replace_ExtraProjectPath()
+ bc.create_test_world()
diff --git a/tests/expected/Human.proto b/tests/expected/Human.proto
index 16dd7c0d..0564c419 100644
--- a/tests/expected/Human.proto
+++ b/tests/expected/Human.proto
@@ -276,6 +276,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.216600
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.000100 0.000200 0.001000
0.000000 0.000000 0.000000
@@ -298,6 +299,7 @@ PROTO Human [
physics Physics {
density -1
mass 1.250000
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.001400 0.003900 0.004100
0.000000 0.000000 0.000000
@@ -320,6 +322,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.100000
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.001000 0.001000 0.001000
0.000000 0.000000 0.000000
@@ -342,6 +345,7 @@ PROTO Human [
physics Physics {
density -1
mass 3.707500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.050400 0.005100 0.051100
0.000000 0.000000 0.000000
@@ -364,6 +368,7 @@ PROTO Human [
physics Physics {
density -1
mass 9.301400
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.133900 0.035100 0.141200
0.000000 0.000000 0.000000
@@ -601,6 +606,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.216600
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.000100 0.000200 0.001000
0.000000 0.000000 0.000000
@@ -623,6 +629,7 @@ PROTO Human [
physics Physics {
density -1
mass 1.250000
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.001400 0.003900 0.004100
0.000000 0.000000 0.000000
@@ -645,6 +652,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.100000
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.001000 0.001000 0.001000
0.000000 0.000000 0.000000
@@ -667,6 +675,7 @@ PROTO Human [
physics Physics {
density -1
mass 3.707500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.050400 0.005100 0.051100
0.000000 0.000000 0.000000
@@ -689,6 +698,7 @@ PROTO Human [
physics Physics {
density -1
mass 9.301400
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.133900 0.035100 0.141200
0.000000 0.000000 0.000000
@@ -926,6 +936,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.457500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.000892 0.000547 0.001340
0.000000 0.000000 0.000000
@@ -948,6 +959,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.607500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.002962 0.000618 0.003213
0.000000 0.000000 0.000000
@@ -970,6 +982,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.607500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.002962 0.000618 0.003213
0.000000 0.000000 0.000000
@@ -992,6 +1005,7 @@ PROTO Human [
physics Physics {
density -1
mass 2.032500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.011946 0.004121 0.013409
0.000000 0.000000 0.000000
@@ -1186,6 +1200,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.457500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.000892 0.000547 0.001340
0.000000 0.000000 0.000000
@@ -1208,6 +1223,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.607500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.002962 0.000618 0.003213
0.000000 0.000000 0.000000
@@ -1230,6 +1246,7 @@ PROTO Human [
physics Physics {
density -1
mass 0.607500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.002962 0.000618 0.003213
0.000000 0.000000 0.000000
@@ -1252,6 +1269,7 @@ PROTO Human [
physics Physics {
density -1
mass 2.032500
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.011946 0.004121 0.013409
0.000000 0.000000 0.000000
@@ -1274,6 +1292,7 @@ PROTO Human [
physics Physics {
density -1
mass 26.826600
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
1.474500 0.755500 1.431400
0.000000 0.000000 0.000000
@@ -1296,6 +1315,7 @@ PROTO Human [
physics Physics {
density -1
mass 11.777000
+ centerOfMass [ 0.000000 0.000000 0.000000 ]
inertiaMatrix [
0.102800 0.087100 0.057900
0.000000 0.000000 0.000000
diff --git a/tests/expected/MotomanSia20d.proto b/tests/expected/MotomanSia20d.proto
index 071e0d17..caf496cd 100644
--- a/tests/expected/MotomanSia20d.proto
+++ b/tests/expected/MotomanSia20d.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# This is a proto file for Webots for the MotomanSia20d
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d [
field SFVec3f translation 0 0 0
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_BMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_BMesh.proto
index 01bcd78c..3165c3b0 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_BMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_BMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_BMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_EMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_EMesh.proto
index e56692a9..e0d46c5a 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_EMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_EMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_EMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_LMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_LMesh.proto
index 4a00b6a8..5893f3d4 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_LMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_LMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_LMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_RMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_RMesh.proto
index 1a0fcf6c..6b39c320 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_RMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_RMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_RMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_SMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_SMesh.proto
index c8279d8b..a98a3970 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_SMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_SMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_SMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_TMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_TMesh.proto
index db03785d..8b2a86a4 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_TMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_TMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_TMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_UMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_UMesh.proto
index da424b68..29012bc4 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_UMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_AXIS_UMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_AXIS_UMesh [
]
diff --git a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_BASEMesh.proto b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_BASEMesh.proto
index 59b3006c..4df0901b 100644
--- a/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_BASEMesh.proto
+++ b/tests/expected/MotomanSia20d_meshes/MotomanSia20d_MOTOMAN_BASEMesh.proto
@@ -2,7 +2,7 @@
# license: Apache License 2.0
# license url: http://www.apache.org/licenses/LICENSE-2.0
# tags: hidden
-# Extracted from: /home/david/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
+# Extracted from: /home/travis/urdf2webots/tests/sources/motoman/motoman_sia20d_support/urdf/sia20d.urdf
PROTO MotomanSia20d_MOTOMAN_BASEMesh [
]
diff --git a/urdf2webots/writeProto.py b/urdf2webots/writeProto.py
index 4b6a64ce..c78f62d2 100644
--- a/urdf2webots/writeProto.py
+++ b/urdf2webots/writeProto.py
@@ -155,10 +155,9 @@ def URDFLink(proto, link, level, parentList, childList, linkList, jointList, sen
proto.write((level + 1) * indent + 'physics Physics {\n')
proto.write((level + 2) * indent + 'density -1\n')
proto.write((level + 2) * indent + 'mass %lf\n' % link.inertia.mass)
- if link.inertia.position != [0.0, 0.0, 0.0]:
- proto.write((level + 2) * indent + 'centerOfMass [ %lf %lf %lf ]\n' % (link.inertia.position[0],
- link.inertia.position[1],
- link.inertia.position[2]))
+ proto.write((level + 2) * indent + 'centerOfMass [ %lf %lf %lf ]\n' % (link.inertia.position[0],
+ link.inertia.position[1],
+ link.inertia.position[2]))
if link.inertia.ixx > 0.0 and link.inertia.iyy > 0.0 and link.inertia.izz > 0.0:
i = link.inertia
inertiaMatrix = [i.ixx, i.ixy, i.ixz, i.ixy, i.iyy, i.iyz, i.ixz, i.iyz, i.izz]
@@ -503,8 +502,8 @@ def URDFShape(proto, link, level, normal=False):
if name is None:
if visualNode.geometry.name is not None:
name = computeDefName(visualNode.geometry.name)
- if visualNode.geometry.defName is None:
- name = robotNameMain + '_' + name if robotNameMain else name
+ name = robotNameMain + '_' + name if robotNameMain else name
+ if visualNode.geometry.defName is None:
print('Create meshFile: %sMesh.proto' % name)
filepath = '%s/%sMesh.proto' % (meshFilesPath, name)
meshProtoFile = open(filepath, 'w')