Первоначальная настройка
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"""One-time, ROS-free export of this repository's known description macros.
|
||||
|
||||
This is deliberately not a general Xacro interpreter. Runtime uses the emitted URDFs.
|
||||
"""
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SOURCE = ROOT / "iiwa_description"
|
||||
DEST = ROOT / "iiwa_genesis_description"
|
||||
NS = "{http://www.ros.org/wiki/xacro}"
|
||||
|
||||
|
||||
def export():
|
||||
props = {}
|
||||
for name in ("params", "meshes"):
|
||||
for node in ET.parse(SOURCE / f"urdf/{name}.xacro").getroot():
|
||||
if node.tag == NS + "property":
|
||||
props[node.get("name")] = node.get("value")
|
||||
|
||||
def substitute(value, variables):
|
||||
for _ in range(8):
|
||||
updated = re.sub(r"\$\{([^}]+)\}", lambda m: variables[m[1]], value)
|
||||
if updated == value:
|
||||
return value
|
||||
value = updated
|
||||
raise ValueError("Unresolved variable")
|
||||
|
||||
macros = {n.get("name"): n for n in ET.parse(SOURCE / "urdf/macros.xacro").getroot()}
|
||||
|
||||
def expand(node):
|
||||
if not node.tag.startswith(NS):
|
||||
return [deepcopy(node)]
|
||||
name = node.tag[len(NS):]
|
||||
if name == "include":
|
||||
return []
|
||||
result = []
|
||||
for template in macros[name]:
|
||||
item = deepcopy(template)
|
||||
for child in item.iter():
|
||||
child.attrib = {k: substitute(v, props | node.attrib) for k, v in child.attrib.items()}
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
def write(robot, path):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
for mesh in robot.iter("mesh"):
|
||||
source = mesh.get("filename")
|
||||
prefix = "package://iiwa_description/resource/meshes/"
|
||||
if not source.startswith(prefix):
|
||||
raise ValueError(source)
|
||||
relative = source[len(prefix):]
|
||||
target = DEST / "urdf/meshes" / relative
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(SOURCE / "resource/meshes" / relative, target)
|
||||
mesh.set("filename", ("meshes/" if path.parent.name == "urdf" else "../urdf/meshes/") + relative)
|
||||
ET.indent(robot)
|
||||
ET.ElementTree(robot).write(path, encoding="utf-8", xml_declaration=True)
|
||||
|
||||
base = ET.Element("robot", name="iiwa7")
|
||||
for name in ("links", "joints"):
|
||||
for node in ET.parse(SOURCE / f"urdf/{name}.xacro").getroot():
|
||||
base.extend(expand(node))
|
||||
write(deepcopy(base), DEST / "urdf/iiwa_without_gripper.urdf")
|
||||
for node in ET.parse(SOURCE / "urdf/tools/patron.xacro").getroot():
|
||||
if node.tag in ("link", "joint"):
|
||||
base.append(deepcopy(node))
|
||||
write(base, DEST / "urdf/iiwa_with_gripper.urdf")
|
||||
write(ET.parse(SOURCE / "urdf/table/table.urdf").getroot(), DEST / "table/table.urdf")
|
||||
shutil.copy2(SOURCE / "LICENSE", DEST / "LICENSE")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
export()
|
||||
Reference in New Issue
Block a user