diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d650d0e0e6d0f8eaea7d5d2a77c451d85067320..52d36559fc41ccba74e5d9dca7a7e82bb9ae09de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ SET(${PROJECT_NAME}_MULTIBODY_HEADERS multibody/model.hpp multibody/model.hxx multibody/visitor.hpp + multibody/parser/srdf.hpp ) SET(${PROJECT_NAME}_ALGORITHM_HEADERS diff --git a/src/multibody/geometry.hxx b/src/multibody/geometry.hxx index 5f0aa0e2d0887a17d94005434eadda16bdd1fa30..b325d6c65e858c7b70b1d767c036f098a08708e2 100644 --- a/src/multibody/geometry.hxx +++ b/src/multibody/geometry.hxx @@ -27,6 +27,7 @@ #include "pinocchio/spatial/fcl-pinocchio-conversions.hpp" #include "pinocchio/multibody/model.hpp" #include "pinocchio/multibody/joint/joint-variant.hpp" +#include "pinocchio/multibody/parser/srdf.hpp" #include <iostream> #include <hpp/fcl/collision_object.h> @@ -36,12 +37,6 @@ #include <list> #include <utility> -// Read XML file with boost -#include <boost/property_tree/xml_parser.hpp> -#include <boost/property_tree/ptree.hpp> -#include <fstream> -#include <boost/foreach.hpp> - /// @cond DEV namespace se3 @@ -304,68 +299,11 @@ namespace se3 void GeometryData::addCollisionPairsFromSrdf(const std::string & filename, const bool verbose) throw (std::invalid_argument) { - // Check extension - const std::string extension = filename.substr(filename.find_last_of('.')+1); - if (extension != "srdf") - { - const std::string exception_message (filename + " does not have the right extension."); - throw std::invalid_argument(exception_message); - } - - // Open file - std::ifstream srdf_stream(filename.c_str()); - if (! srdf_stream.is_open()) - { - const std::string exception_message (filename + " does not seem to be a valid file."); - throw std::invalid_argument(exception_message); - } - // Add all collision pairs addAllCollisionPairs(); - // Read xml stream - using boost::property_tree::ptree; - ptree pt; - read_xml(srdf_stream, pt); - - // Iterate over collision pairs - const se3::Model & model = data_ref.model; - BOOST_FOREACH(const ptree::value_type & v, pt.get_child("robot")) - { - if (v.first == "disable_collisions") - { - const std::string link1 = v.second.get<std::string>("<xmlattr>.link1"); - const std::string link2 = v.second.get<std::string>("<xmlattr>.link2"); - - // Check first if the two bodies exist in model - if (!model.existBodyName(link1) || !model.existBodyName(link2)) - { - if (verbose) - std::cout << "It seems that " << link1 << " or " << link2 << " do not exist in model. Skip." << std::endl; - continue; - } - - const Model::JointIndex id1 = model.getBodyId(link1); - const Model::JointIndex id2 = model.getBodyId(link2); - - typedef GeometryModel::GeomIndexList GeomIndexList; - const GeomIndexList & innerObject1 = model_geom.innerObjects.at(id1); - const GeomIndexList & innerObject2 = model_geom.innerObjects.at(id2); - - for(GeomIndexList::const_iterator it1 = innerObject1.begin(); - it1 != innerObject1.end(); - ++it1) - { - for(GeomIndexList::const_iterator it2 = innerObject2.begin(); - it2 != innerObject2.end(); - ++it2) - { - removeCollisionPair(CollisionPair(*it1, *it2)); - } - } - - } // BOOST_FOREACH - } + // Read SRDF file + srdf::removeCollisionPairsFromSrdf(model_geom, *this, filename, verbose); } diff --git a/src/multibody/parser/srdf.hpp b/src/multibody/parser/srdf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..511d4fb2acb0181b2439bcc1117ad42bb7e6bfec --- /dev/null +++ b/src/multibody/parser/srdf.hpp @@ -0,0 +1,115 @@ +// +// Copyright (c) 2016 CNRS +// +// This file is part of Pinocchio +// Pinocchio is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version +// 3 of the License, or (at your option) any later version. +// +// Pinocchio is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. You should have +// received a copy of the GNU Lesser General Public License along with +// Pinocchio If not, see +// <http://www.gnu.org/licenses/>. + +#ifndef __se3_parser_srdf_hpp__ +#define __se3_parser_srdf_hpp__ + +#include "pinocchio/multibody/model.hpp" +#include <iostream> + +// Read XML file with boost +#include <boost/property_tree/xml_parser.hpp> +#include <boost/property_tree/ptree.hpp> +#include <fstream> +#include <boost/foreach.hpp> + + +namespace se3 +{ + namespace srdf + { + +#ifdef WITH_HPP_FCL + /// + /// \brief Deactive all possible collision pairs mentioned in the SRDF file. + /// It throws if the SRDF file is incorrect. + /// + /// \param[in] filename The complete path to the SRDF file. + /// \param[in] verbose Verbosity mode. + /// + inline void removeCollisionPairsFromSrdf(const GeometryModel & model_geom, + GeometryData & data_geom, + const std::string & filename, + const bool verbose) throw (std::invalid_argument) + { + // Check extension + const std::string extension = filename.substr(filename.find_last_of('.')+1); + if (extension != "srdf") + { + const std::string exception_message (filename + " does not have the right extension."); + throw std::invalid_argument(exception_message); + } + + // Open file + std::ifstream srdf_stream(filename); + if (! srdf_stream.is_open()) + { + const std::string exception_message (filename + " does not seem to be a valid file."); + throw std::invalid_argument(exception_message); + } + + // Read xml stream + using boost::property_tree::ptree; + ptree pt; + read_xml(srdf_stream, pt); + + // Iterate over collision pairs + const se3::Model & model = model_geom.model; + BOOST_FOREACH(const ptree::value_type & v, pt.get_child("robot")) + { + if (v.first == "disable_collisions") + { + const std::string link1 = v.second.get<std::string>("<xmlattr>.link1"); + const std::string link2 = v.second.get<std::string>("<xmlattr>.link2"); + + // Check first if the two bodies exist in model + if (!model.existBodyName(link1) || !model.existBodyName(link2)) + { + if (verbose) + std::cout << "It seems that " << link1 << " or " << link2 << " do not exist in model. Skip." << std::endl; + continue; + } + + const Model::JointIndex id1 = model.getBodyId(link1); + const Model::JointIndex id2 = model.getBodyId(link2); + + typedef GeometryModel::GeomIndexList GeomIndexList; + const GeomIndexList & innerObject1 = model_geom.innerObjects.at(id1); + const GeomIndexList & innerObject2 = model_geom.innerObjects.at(id2); + + for(GeomIndexList::const_iterator it1 = innerObject1.begin(); + it1 != innerObject1.end(); + ++it1) + { + for(GeomIndexList::const_iterator it2 = innerObject2.begin(); + it2 != innerObject2.end(); + ++it2) + { + data_geom.removeCollisionPair(CollisionPair(*it1, *it2)); + } + } + + } + } // BOOST_FOREACH + } + +#endif // ifdef WITH_HPP_FCL + + } +} // namespace se3 + +#endif // ifndef __se3_parser_srdf_hpp__