【问题标题】:How can I parse "package://" in a URDF file path?如何在 URDF 文件路径中解析 \"package://\"?
【发布时间】:2023-01-09 20:40:41
【问题描述】:

我有一个机器人 URDF,它使用“package://”指向网格文件。

  <geometry>
    <mesh filename="package://a1_rw/meshes/hip.dae" scale="1 1 1"/>
  </geometry>

我想使用 urdfpy 来解析这个 URDF。但是,它无法解释“package://”的含义。

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 解析器)正确解析这个?

【问题讨论】:

    标签: path robotics


    【解决方案1】:

    您观察到的行为是预期的。 urdfpy.URDF.load() 的文档明确指出:

    URDF 中的任何路径都应指定为 .urdf 文件的相对路径,而不是 ROS 资源。

    如果您想继续使用同一个库,解决这个问题的唯一方法是替换.urdf 文件中的字符串。为此,我建议使用 temporary file,以便在您加载 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-08
      • 2018-09-11
      • 2014-09-03
      • 2013-06-05
      • 2013-06-04
      • 2016-05-30
      • 2011-04-18
      • 1970-01-01
      相关资源
      最近更新 更多