-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodify_robot.py
executable file
·115 lines (105 loc) · 4.6 KB
/
modify_robot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3
from urchin import URDF
from enums import Limb
from pathlib import Path
from modifiers import get_modifiers
import argparse
import configparser
import os
def write_urdf_to_file(urdf, filename, gazebo_plugins):
"""Saves the URDF to a valid .urdf file, also adding the gazebo_plugins"""
urdf.save(filename)
lines = ''
with open(filename, 'r') as f:
lines = f.readlines()
lines.pop()
lines = lines + gazebo_plugins
with open(filename, 'w') as f:
f.writelines(lines)
def separate_gazebo_plugins(filename):
"""Splits the URDF content in two parts: one relative to the robot and another to the gazebo plugins"""
gazebo_lines = []
other_lines= []
with open(filename, "r") as f:
lines = f.readlines()
is_gazebo = False
for line in lines:
if '<gazebo' in line or '< gazebo' in line:
is_gazebo = True
if (is_gazebo):
gazebo_lines.append(line)
else:
other_lines.append(line)
other_lines.append('</robot>')
return [other_lines, gazebo_lines]
def create_dummy_file(dummy_filename, text):
"""Creates a dummy file to save information"""
with open(dummy_filename, 'w') as f:
f.writelines(text)
def parse_modifications(config_section):
"""Returns the modifications from a section of the ini file"""
modifications = {}
dimension_scale = config_section.get('dimension_scale', None)
if dimension_scale is not None:
modifications["dimension"] = [float(dimension_scale), False]
density_scale = config_section.get('density_scale', None)
if density_scale is not None:
modifications["density"] = [float(density_scale), False]
radius_scale = config_section.get('radius_scale', None)
if radius_scale is not None:
modifications["radius"] = [float(radius_scale), False]
mass_scale = config_section.get('mass_scale', None)
if mass_scale is not None:
modifications["mass"] = [float(mass_scale), False]
dimension = config_section.get('dimension', None)
if dimension is not None:
modifications["dimension"] = [float(dimension), True]
density = config_section.get('density', None)
if density is not None:
modifications["density"] = [float(density), True]
radius = config_section.get('radius', None)
if radius is not None:
modifications["radius"] = [float(radius), True]
mass = config_section.get('mass', None)
if mass is not None:
modifications["mass"] = [float(mass), True]
return modifications
def erase_dummy_file(dummy_filename):
"""Erases the dummy file"""
os.remove(dummy_filename)
def install_urdf():
"""Uses Make to install the URDF in the build folder to the Gazebo path"""
os.system("cd ../build && make install -j4")
def main(filename, dummy_file, config_file_path, should_reset):
export_filename = "../build/models/stickBot/model.urdf"
if (should_reset):
os.system(f"cp {filename} {export_filename}")
else:
# The urdfpy library does not read the gazebo plugins well so they need to be
# stripped from the file before parsing it
main_urdf, gazebo_plugin_text = separate_gazebo_plugins(filename)
create_dummy_file(dummy_file, main_urdf)
robot = URDF.load(dummy_file)
erase_dummy_file(dummy_file)
config = configparser.ConfigParser()
config.read(config_file_path)
for config_section in config.sections():
modifications = parse_modifications(config[config_section])
if config_section.upper() in Limb:
selector = Limb[config_section.upper()]
else:
selector = config_section
elements_to_modify = get_modifiers(robot, selector)
for element_to_modify in elements_to_modify:
element_to_modify.modify(modifications)
write_urdf_to_file(robot, export_filename, gazebo_plugin_text)
install_urdf()
if __name__ == "__main__":
dummy_file = 'no_gazebo_plugins.urdf'
parser = argparse.ArgumentParser(description = "Modifies a Stick-Bot URDF file")
parser.add_argument('filename', nargs='?', help="The filename of the robot's URDF", default="../models/stickBot/model.urdf")
parser.add_argument('-c', '--config', help="Path to configuration file", default="conf.ini")
parser.add_argument('-r', '--reset', help="Sets the robot back to latest version in Git", action="store_true")
args = parser.parse_args()
if args.filename is not None:
main(args.filename, dummy_file, args.config, args.reset)