00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00037 #include <moveit/robot_model/robot_model.h>
00038 #include <moveit/robot_state/robot_state.h>
00039 #include <moveit/transforms/transforms.h>
00040 #include <moveit/collision_distance_field/collision_distance_field_types.h>
00041 #include <moveit/collision_distance_field/collision_robot_distance_field.h>
00042 #include <moveit/collision_distance_field/collision_world_distance_field.h>
00043 #include <moveit_resources/config.h>
00044 
00045 #include <geometric_shapes/shape_operations.h>
00046 #include <urdf_parser/urdf_parser.h>
00047 
00048 #include <fstream>
00049 #include <gtest/gtest.h>
00050 #include <sstream>
00051 #include <algorithm>
00052 #include <ctype.h>
00053 #include <boost/filesystem.hpp>
00054 
00055 typedef collision_detection::CollisionWorldDistanceField DefaultCWorldType;
00056 typedef collision_detection::CollisionRobotDistanceField DefaultCRobotType;
00057 
00058 class DistanceFieldCollisionDetectionTester : public testing::Test
00059 {
00060 protected:
00061   virtual void SetUp()
00062   {
00063     srdf_model_.reset(new srdf::Model());
00064     std::string xml_string;
00065     std::fstream xml_file(MOVEIT_TEST_RESOURCES_DIR "/pr2_description/urdf/robot.xml", std::fstream::in);
00066     if (xml_file.is_open())
00067     {
00068       while (xml_file.good())
00069       {
00070         std::string line;
00071         std::getline(xml_file, line);
00072         xml_string += (line + "\n");
00073       }
00074       xml_file.close();
00075       urdf_model_ = urdf::parseURDF(xml_string);
00076       urdf_ok_ = urdf_model_ ? true : false;
00077     }
00078     else
00079       urdf_ok_ = false;
00080     srdf_ok_ = srdf_model_->initFile(*urdf_model_, MOVEIT_TEST_RESOURCES_DIR "/pr2_description/srdf/robot.xml");
00081 
00082     robot_model_.reset(new robot_model::RobotModel(urdf_model_, srdf_model_));
00083 
00084     acm_.reset(new collision_detection::AllowedCollisionMatrix(robot_model_->getLinkModelNames(), true));
00085 
00086     std::map<std::string, std::vector<collision_detection::CollisionSphere>> link_body_decompositions;
00087     crobot_.reset(new DefaultCRobotType(robot_model_, link_body_decompositions));
00088     cworld_.reset(new DefaultCWorldType());
00089   }
00090 
00091   virtual void TearDown()
00092   {
00093   }
00094 
00095 protected:
00096   bool urdf_ok_;
00097   bool srdf_ok_;
00098 
00099   boost::shared_ptr<urdf::ModelInterface> urdf_model_;
00100   boost::shared_ptr<srdf::Model> srdf_model_;
00101 
00102   robot_model::RobotModelPtr robot_model_;
00103 
00104   robot_state::TransformsPtr ftf_;
00105   robot_state::TransformsConstPtr ftf_const_;
00106 
00107   boost::shared_ptr<collision_detection::CollisionRobot> crobot_;
00108   boost::shared_ptr<collision_detection::CollisionWorld> cworld_;
00109 
00110   collision_detection::AllowedCollisionMatrixPtr acm_;
00111 };
00112 
00113 TEST_F(DistanceFieldCollisionDetectionTester, DefaultNotInCollision)
00114 {
00115   robot_state::RobotState kstate(robot_model_);
00116   kstate.setToDefaultValues();
00117   kstate.update();
00118 
00119   ASSERT_TRUE(urdf_ok_ && srdf_ok_);
00120 
00121   collision_detection::CollisionRequest req;
00122   collision_detection::CollisionResult res;
00123   req.group_name = "whole_body";
00124   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00125   ASSERT_FALSE(res.collision);
00126 }
00127 
00128 TEST_F(DistanceFieldCollisionDetectionTester, ChangeTorsoPosition)
00129 {
00130   robot_state::RobotState kstate(robot_model_);
00131   kstate.setToDefaultValues();
00132   kstate.update();
00133 
00134   collision_detection::CollisionRequest req;
00135   collision_detection::CollisionResult res1;
00136   collision_detection::CollisionResult res2;
00137 
00138   req.group_name = "right_arm";
00139   crobot_->checkSelfCollision(req, res1, kstate, *acm_);
00140   std::map<std::string, double> torso_val;
00141   torso_val["torso_lift_joint"] = .15;
00142   kstate.setVariablePositions(torso_val);
00143   kstate.update();
00144   crobot_->checkSelfCollision(req, res1, kstate, *acm_);
00145   crobot_->checkSelfCollision(req, res1, kstate, *acm_);
00146 }
00147 
00148 TEST_F(DistanceFieldCollisionDetectionTester, LinksInCollision)
00149 {
00150   collision_detection::CollisionRequest req;
00151   collision_detection::CollisionResult res1;
00152   collision_detection::CollisionResult res2;
00153   collision_detection::CollisionResult res3;
00154   
00155   
00156   req.group_name = "whole_body";
00157 
00158   robot_state::RobotState kstate(robot_model_);
00159   kstate.setToDefaultValues();
00160 
00161   Eigen::Affine3d offset = Eigen::Affine3d::Identity();
00162   offset.translation().x() = .01;
00163 
00164   kstate.updateStateWithLinkAt("base_link", Eigen::Affine3d::Identity());
00165   kstate.updateStateWithLinkAt("base_bellow_link", offset);
00166 
00167   acm_->setEntry("base_link", "base_bellow_link", false);
00168   crobot_->checkSelfCollision(req, res1, kstate, *acm_);
00169   ASSERT_TRUE(res1.collision);
00170 
00171   acm_->setEntry("base_link", "base_bellow_link", true);
00172   crobot_->checkSelfCollision(req, res2, kstate, *acm_);
00173   ASSERT_FALSE(res2.collision);
00174 
00175   kstate.updateStateWithLinkAt("r_gripper_palm_link", Eigen::Affine3d::Identity());
00176   kstate.updateStateWithLinkAt("l_gripper_palm_link", offset);
00177 
00178   acm_->setEntry("r_gripper_palm_link", "l_gripper_palm_link", false);
00179   crobot_->checkSelfCollision(req, res3, kstate, *acm_);
00180   ASSERT_TRUE(res3.collision);
00181 }
00182 
00183 TEST_F(DistanceFieldCollisionDetectionTester, ContactReporting)
00184 {
00185   collision_detection::CollisionRequest req;
00186   req.contacts = true;
00187   req.max_contacts = 1;
00188   req.group_name = "whole_body";
00189 
00190   robot_state::RobotState kstate(robot_model_);
00191   kstate.setToDefaultValues();
00192 
00193   Eigen::Affine3d offset = Eigen::Affine3d::Identity();
00194   offset.translation().x() = .01;
00195 
00196   kstate.updateStateWithLinkAt("base_link", Eigen::Affine3d::Identity());
00197   kstate.updateStateWithLinkAt("base_bellow_link", offset);
00198 
00199   kstate.updateStateWithLinkAt("r_gripper_palm_link", Eigen::Affine3d::Identity());
00200   kstate.updateStateWithLinkAt("l_gripper_palm_link", offset);
00201 
00202   acm_->setEntry("base_link", "base_bellow_link", false);
00203   acm_->setEntry("r_gripper_palm_link", "l_gripper_palm_link", false);
00204 
00205   collision_detection::CollisionResult res;
00206   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00207   ASSERT_TRUE(res.collision);
00208   EXPECT_EQ(res.contacts.size(), 1);
00209   EXPECT_EQ(res.contacts.begin()->second.size(), 1);
00210 
00211   res.clear();
00212   req.max_contacts = 2;
00213   req.max_contacts_per_pair = 1;
00214   
00215   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00216   ASSERT_TRUE(res.collision);
00217   EXPECT_EQ(res.contact_count, 2);
00218   EXPECT_EQ(res.contacts.begin()->second.size(), 1);
00219 
00220   res.contacts.clear();
00221   res.contact_count = 0;
00222 
00223   req.max_contacts = 10;
00224   req.max_contacts_per_pair = 2;
00225   acm_.reset(new collision_detection::AllowedCollisionMatrix(robot_model_->getLinkModelNames(), false));
00226   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00227   ASSERT_TRUE(res.collision);
00228   EXPECT_LE(res.contacts.size(), 10);
00229   EXPECT_LE(res.contact_count, 10);
00230 }
00231 
00232 TEST_F(DistanceFieldCollisionDetectionTester, ContactPositions)
00233 {
00234   collision_detection::CollisionRequest req;
00235   req.contacts = true;
00236   req.max_contacts = 1;
00237   req.group_name = "whole_body";
00238 
00239   robot_state::RobotState kstate(robot_model_);
00240   kstate.setToDefaultValues();
00241 
00242   Eigen::Affine3d pos1 = Eigen::Affine3d::Identity();
00243   Eigen::Affine3d pos2 = Eigen::Affine3d::Identity();
00244 
00245   pos1.translation().x() = 5.0;
00246   pos2.translation().x() = 5.01;
00247 
00248   kstate.updateStateWithLinkAt("r_gripper_palm_link", pos1);
00249   kstate.updateStateWithLinkAt("l_gripper_palm_link", pos2);
00250 
00251   acm_->setEntry("r_gripper_palm_link", "l_gripper_palm_link", false);
00252 
00253   collision_detection::CollisionResult res;
00254   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00255   ASSERT_TRUE(res.collision);
00256   ASSERT_EQ(res.contacts.size(), 1);
00257   ASSERT_EQ(res.contacts.begin()->second.size(), 1);
00258 
00259   for (collision_detection::CollisionResult::ContactMap::const_iterator it = res.contacts.begin();
00260        it != res.contacts.end(); it++)
00261   {
00262     EXPECT_NEAR(it->second[0].pos.x(), 5.0, .33);
00263   }
00264 
00265   pos1 = Eigen::Affine3d(Eigen::Translation3d(3.0, 0.0, 0.0) * Eigen::Quaterniond::Identity());
00266   pos2 = Eigen::Affine3d(Eigen::Translation3d(3.0, 0.0, 0.0) * Eigen::Quaterniond(0.965, 0.0, 0.258, 0.0));
00267 
00268   kstate.updateStateWithLinkAt("r_gripper_palm_link", pos1);
00269   kstate.updateStateWithLinkAt("l_gripper_palm_link", pos2);
00270 
00271   collision_detection::CollisionResult res2;
00272   crobot_->checkSelfCollision(req, res2, kstate, *acm_);
00273   ASSERT_TRUE(res2.collision);
00274   ASSERT_EQ(res2.contacts.size(), 1);
00275   ASSERT_EQ(res2.contacts.begin()->second.size(), 1);
00276 
00277   for (collision_detection::CollisionResult::ContactMap::const_iterator it = res2.contacts.begin();
00278        it != res2.contacts.end(); it++)
00279   {
00280     EXPECT_NEAR(it->second[0].pos.x(), 3.0, 0.33);
00281   }
00282 
00283   pos1 = Eigen::Affine3d(Eigen::Translation3d(3.0, 0.0, 0.0) * Eigen::Quaterniond::Identity());
00284   pos2 = Eigen::Affine3d(Eigen::Translation3d(3.0, 0.0, 0.0) * Eigen::Quaterniond(M_PI / 4.0, 0.0, M_PI / 4.0, 0.0));
00285 
00286   kstate.updateStateWithLinkAt("r_gripper_palm_link", pos1);
00287   kstate.updateStateWithLinkAt("l_gripper_palm_link", pos2);
00288 
00289   collision_detection::CollisionResult res3;
00290   crobot_->checkSelfCollision(req, res2, kstate, *acm_);
00291   ASSERT_FALSE(res3.collision);
00292 }
00293 
00294 TEST_F(DistanceFieldCollisionDetectionTester, AttachedBodyTester)
00295 {
00296   collision_detection::CollisionRequest req;
00297   collision_detection::CollisionResult res;
00298 
00299   req.group_name = "right_arm";
00300 
00301   acm_.reset(new collision_detection::AllowedCollisionMatrix(robot_model_->getLinkModelNames(), true));
00302 
00303   robot_state::RobotState kstate(robot_model_);
00304   kstate.setToDefaultValues();
00305   kstate.update();
00306 
00307   Eigen::Affine3d pos1 = Eigen::Affine3d::Identity();
00308   pos1.translation().x() = 1.0;
00309 
00310   kstate.updateStateWithLinkAt("r_gripper_palm_link", pos1);
00311   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00312   ASSERT_FALSE(res.collision);
00313 
00314   shapes::Shape* shape = new shapes::Box(.25, .25, .25);
00315   cworld_->getWorld()->addToObject("box", shapes::ShapeConstPtr(shape), pos1);
00316 
00317   res = collision_detection::CollisionResult();
00318   cworld_->checkRobotCollision(req, res, *crobot_, kstate, *acm_);
00319   ASSERT_TRUE(res.collision);
00320 
00321   
00322   cworld_->getWorld()->removeObject("box");
00323 
00324   std::vector<shapes::ShapeConstPtr> shapes;
00325   EigenSTL::vector_Affine3d poses;
00326   shapes.push_back(shapes::ShapeConstPtr(new shapes::Box(.25, .25, .25)));
00327   poses.push_back(Eigen::Affine3d::Identity());
00328   std::set<std::string> touch_links;
00329   trajectory_msgs::JointTrajectory empty_state;
00330   robot_state::AttachedBody* attached_body = new robot_state::AttachedBody(
00331       kstate.getLinkModel("r_gripper_palm_link"), "box", shapes, poses, touch_links, empty_state);
00332 
00333   kstate.attachBody(attached_body);
00334 
00335   res = collision_detection::CollisionResult();
00336   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00337   ASSERT_TRUE(res.collision);
00338 
00339   
00340   kstate.clearAttachedBody("box");
00341 
00342   touch_links.insert("r_gripper_palm_link");
00343   shapes[0].reset(new shapes::Box(.1, .1, .1));
00344 
00345   robot_state::AttachedBody* attached_body_1 = new robot_state::AttachedBody(
00346       kstate.getLinkModel("r_gripper_palm_link"), "box", shapes, poses, touch_links, empty_state);
00347   kstate.attachBody(attached_body_1);
00348 
00349   res = collision_detection::CollisionResult();
00350   crobot_->checkSelfCollision(req, res, kstate, *acm_);
00351   
00352 
00353   pos1.translation().x() = 1.01;
00354   shapes::Shape* coll = new shapes::Box(.1, .1, .1);
00355   cworld_->getWorld()->addToObject("coll", shapes::ShapeConstPtr(coll), pos1);
00356   res = collision_detection::CollisionResult();
00357   cworld_->checkRobotCollision(req, res, *crobot_, kstate, *acm_);
00358   ASSERT_TRUE(res.collision);
00359 
00360   acm_->setEntry("coll", "r_gripper_palm_link", true);
00361   res = collision_detection::CollisionResult();
00362   cworld_->checkRobotCollision(req, res, *crobot_, kstate, *acm_);
00363   ASSERT_TRUE(res.collision);
00364 }
00365 
00366 int main(int argc, char** argv)
00367 {
00368   testing::InitGoogleTest(&argc, argv);
00369   return RUN_ALL_TESTS();
00370 }