我有一个机器人URDF,它使用";包装://";。
<geometry>
<mesh filename="package://a1_rw/meshes/hip.dae" scale="1 1 1"/>
</geometry>
我想使用urdfpy来解析这个URDF。然而,它无法解释";包装://";。
import os
from urdfpy import URDF
a1_rw = {
"model": "a1",
"csvpath": "a1_rw/urdf/a1_rw.csv",
"urdfpath": "a1_rw/urdf/a1_rw.urdf"
}
model = a1_rw
curdir = os.getcwd()
path_parent = os.path.dirname(curdir)
print("path parent = ", path_parent)
model_path = model["urdfpath"]
robot = URDF.load(os.path.join(path_parent, model_path))
这是错误消息:
$ python3.8 calc_parallax.py
path parent = /home/ben/Documents/git_workspace/a1_test
Traceback (most recent call last):
File "calc_parallax.py", line 18, in <module>
robot = URDF.load(os.path.join(path_parent, model_path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 3729, in load
return URDF._from_xml(node, path)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 3926, in _from_xml
kwargs = cls._parse(node, path)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 161, in _parse
kwargs.update(cls._parse_simple_elements(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 137, in _parse_simple_elements
v = [t._from_xml(n, path) for n in vs]
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 137, in <listcomp>
v = [t._from_xml(n, path) for n in vs]
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 181, in _from_xml
return cls(**cls._parse(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 161, in _parse
kwargs.update(cls._parse_simple_elements(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 137, in _parse_simple_elements
v = [t._from_xml(n, path) for n in vs]
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 137, in <listcomp>
v = [t._from_xml(n, path) for n in vs]
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 1146, in _from_xml
kwargs = cls._parse(node, path)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 161, in _parse
kwargs.update(cls._parse_simple_elements(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 127, in _parse_simple_elements
v = t._from_xml(v, path)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 181, in _from_xml
return cls(**cls._parse(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 161, in _parse
kwargs.update(cls._parse_simple_elements(node, path))
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 127, in _parse_simple_elements
v = t._from_xml(v, path)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/urdf.py", line 581, in _from_xml
meshes = load_meshes(fn)
File "/home/ben/.local/lib/python3.8/site-packages/urdfpy/utils.py", line 225, in load_meshes
meshes = trimesh.load(filename)
File "/home/ben/.local/lib/python3.8/site-packages/trimesh/exchange/load.py", line 111, in load
) = parse_file_args(file_obj=file_obj,
File "/home/ben/.local/lib/python3.8/site-packages/trimesh/exchange/load.py", line 623, in parse_file_args
raise ValueError('string is not a file: {}'.format(file_obj))
ValueError: string is not a file: /home/ben/Documents/git_workspace/a1_test/a1_rw/urdf/package://a1_rw/meshes/trunk.dae
有什么方法可以让urdfpy(或另一个urdf解析器(正确地解析它吗?
您观察到的行为是意料之中的。urdfpy.URDF.load()
的文档特别指出:
URDF中的任何路径都应指定为
.urdf
文件的相对路径,而不是ROS资源。
如果您想继续使用同一个库,唯一的解决方法就是替换.urdf
文件中的字符串。要做到这一点,我建议使用一个临时文件,这样一旦你加载了URDF,它就会被自动丢弃,而不会真正影响你的原始URDF。
from pathlib import Path
from urdfpy import URDF
import tempfile
# URDF file (pathlib is a little nicer but not mandatory)
urdf_file_path = Path("path/to/my/file.urdf")
# Define how you replace your string. Adjust it so it fits your file organization
ros_url_prefix = "package://"
abs_path_prefix = "/path/to/my/meshes/folder"
# Start with openning a temp dir (context manger makes it easy to handle)
with tempfile.TemporaryDirectory() as tmpdirname:
# Where your tmpfile will be
tmp_file_path = Path(tmpdirname)/urdf_file_path.name
# Write each line in fout replacing the ros url prefix with abs path
with open(urdf_file_path, 'r') as fin:
with open(tmp_file_path, 'w') as fout:
for line in fin:
fout.write(line.replace(ros_url_prefix, abs_path_prefix))
# Load the urdf from the corrected tmp file
robot_urdf = load(tmp_file_path)
# Here we get out of tmpfile context manager, so the tmpdir and all its content is erased
robot_urdf.show() # The robot urdf is still accessible