rock-control / control-kdl_parser

Library for parsing URDF files into KDL kinematic tree. Ported from ROS.
Other
3 stars 6 forks source link

Nested models and <world> tag #7

Closed alexfneves closed 7 years ago

alexfneves commented 7 years ago

I have a sdf file that looks like the attached file. ship.txt

I want to open this file with kdl_parser to get a tree that will have the two models together. I used kdl_parser::treeFromFile with the file path and format ROBOT_MODEL_SDF, and I got this error:

Error [SDF.cc:128] Tried to use callback in sdf::findFile(), but the callback is empty.  Did you call sdf::setFindCallback()?Error [parser.cc:692] Unable to find uri[model://robot]
[20170815-10:14:39:439] [ERROR] - kdl_parser::the <model> tag not exists (.../control/kdl_parser/src/sdf.cpp:350 - bool kdl_parser::treeFromSdfString(const string&, KDL::Tree&))

If I move the<model> out of the <world>, I get this other error:

Error [SDF.cc:128] Tried to use callback in sdf::findFile(), but the callback is empty.  Did you call sdf::setFindCallback()?Error [parser.cc:692] Unable to find uri[model://robot] 

Gazebo is able to open this file, and the includes work because of the exported variable GAZEBO_MODEL_PATH that points to the robot and ship models.

Is there a way to do this @doudou ?

doudou commented 7 years ago

Is there a way to do this @doudou ?

The way all of this has always been integrated so far - i.e. in the flatfish project - was by getting the ruby layer to load the SDF and resolve the model:// tags and then feed the resolved SDF to the underlying components.

Gazebo-compatible implementation for searching in the path is in gazebo itself, and therefore cannot be used here. To get the same behavior, we would need to reimplement the search.

Would resolving the SDF first from within Ruby and then passing the resolved SDF string to your component/library be an option ?

alexfneves commented 7 years ago

Would resolving the SDF first from within Ruby and then passing the resolved SDF string to your component/library be an option ?

Yes, it should be fine to do this. I would use kdl_parser::treeFromString() with the string.

alexfneves commented 7 years ago

I couldn't find a script that would do that in github and on the BIR flatfish repositories. Do you know where can I find it?

Also, I was led to believe that the flat_fish model.sdf was in the repo Brazilian-Institute-of-Robotics/robots-flat_fish.git but couldn't find this repo. Was the script on that repo?

doudou commented 7 years ago

You can't find the robots/flat_fish package because it is private to the BIR organization.

There wasn't any script because it was done within the Syskit app. The job is basically done by the ruby SDF library which resolves the recursive references between models.

A working script:

#! /usr/bin/env ruby

require 'sdf'
require 'rock/gazebo'

# Automatically adds the current bundle models to the path
Rock::Bundles.load
SDF::XML.model_path = Rock::Gazebo.default_model_path
# Do the resolution, returns a REXML::Document
rexml = SDF::XML.load_sdf(ARGV[0])
# Write to output
rexml.write(STDOUT, 2)
# To write to a string, use a StringIO object instead of STDOUT
alexfneves commented 7 years ago

Many thanks, it worked. I removed the <world ..> and </world> tags from the resulting string in C++ then I got the whole tree with

kdl_parser::treeFromString(str, tree, kdl_parser::ROBOT_MODEL_SDF);
doudou commented 7 years ago

I removed the <world ..> and tags from the resulting string in C++

If only want the model. Just load model://your_model_name instead of the whole world file.