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 "planning_environment/models/collision_models.h"
00038 #include <collision_space/environmentODE.h>
00039 #include <collision_space/environmentBullet.h>
00040 #include <sstream>
00041 #include <vector>
00042
00043 void planning_environment::CollisionModels::setupModel(boost::shared_ptr<collision_space::EnvironmentModel> &model, const std::vector<std::string>& links)
00044 {
00045 XmlRpc::XmlRpcValue coll_ops;
00046
00047
00048 if(!nh_.hasParam(description_ + "_collision/default_collision_operations")) {
00049 ROS_WARN("No default collision operations specified");
00050 } else {
00051
00052 nh_.getParam(description_ + "_collision/default_collision_operations", coll_ops);
00053
00054 if(coll_ops.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00055 ROS_WARN("default_collision_operations is not an array");
00056 return;
00057 }
00058
00059 if(coll_ops.size() == 0) {
00060 ROS_WARN("No collision operations in default collision operations");
00061 return;
00062 }
00063
00064 for(int i = 0; i < coll_ops.size(); i++) {
00065 if(!coll_ops[i].hasMember("object1") || !coll_ops[i].hasMember("object2") || !coll_ops[i].hasMember("operation")) {
00066 ROS_WARN("All collision operations must have two objects and an operation");
00067 continue;
00068 }
00069 motion_planning_msgs::CollisionOperation collision_operation;
00070 collision_operation.object1 = std::string(coll_ops[i]["object1"]);
00071 collision_operation.object2 = std::string(coll_ops[i]["object2"]);
00072 std::string operation = std::string(coll_ops[i]["operation"]);
00073 if(operation == "enable") {
00074 collision_operation.operation = motion_planning_msgs::CollisionOperation::ENABLE;
00075 } else if(operation == "disable") {
00076 collision_operation.operation = motion_planning_msgs::CollisionOperation::DISABLE;
00077 } else {
00078 ROS_WARN_STREAM("Unrecognized collision operation " << operation << ". Must be enable or disable");
00079 continue;
00080 }
00081 default_collision_operations_.push_back(collision_operation);
00082 }
00083 }
00084
00085
00086
00087
00088 ros::NodeHandle priv("~");
00089
00090 priv.param("default_robot_padding", padd_, 0.01);
00091 priv.param("robot_scale", scale_, 1.0);
00092
00093
00094
00095 std::map<std::string, double> link_padding_map;
00096
00097 if(priv.hasParam("link_padding")) {
00098 XmlRpc::XmlRpcValue link_padding_xml;
00099 priv.getParam("link_padding", link_padding_xml);
00100 if(link_padding_xml.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00101 ROS_WARN("link_padding is not an array");
00102 } else if(link_padding_xml.size() == 0) {
00103 ROS_WARN("No links specified in link_padding");
00104 } else {
00105 for(int i = 0; i < link_padding_xml.size(); i++) {
00106 if(!link_padding_xml[i].hasMember("link") || !link_padding_xml[i].hasMember("padding")) {
00107 ROS_WARN("Each entry in link padding must specify a link and a padding");
00108 continue;
00109 }
00110 std::string link = std::string(link_padding_xml[i]["link"]);
00111 double padding = link_padding_xml[i]["padding"];
00112 std::vector<std::string> svec1;
00113 if(planning_group_links_.find(link) != planning_group_links_.end()) {
00114 svec1 = planning_group_links_[link];
00115 } else {
00116 svec1.push_back(link);
00117 }
00118 for(std::vector<std::string>::iterator it = svec1.begin();
00119 it != svec1.end();
00120 it++) {
00121 link_padding_map[*it] = padding;
00122 }
00123 }
00124 }
00125 }
00126
00127 model->lock();
00128 model->setRobotModel(kmodel_, links, link_padding_map, padd_,scale_);
00129
00130 for(std::vector<motion_planning_msgs::CollisionOperation>::iterator it = default_collision_operations_.begin();
00131 it != default_collision_operations_.end();
00132 it++) {
00133 std::vector<std::string> svec1;
00134 std::vector<std::string> svec2;
00135 if(planning_group_links_.find((*it).object1) != planning_group_links_.end()) {
00136 svec1 = planning_group_links_[(*it).object1];
00137 } else {
00138 svec1.push_back((*it).object1);
00139 }
00140 if(planning_group_links_.find((*it).object2) != planning_group_links_.end()) {
00141 svec2 = planning_group_links_[(*it).object2];
00142 } else {
00143 svec2.push_back((*it).object2);
00144 }
00145 if((*it).operation == motion_planning_msgs::CollisionOperation::ENABLE) {
00146 model->addSelfCollisionGroup(svec1,svec2);
00147 } else {
00148 model->removeSelfCollisionGroup(svec1,svec2);
00149 }
00150 }
00151 for (unsigned int i = 0 ; i < boundingPlanes_.size() / 4 ; ++i)
00152 {
00153 shapes::Plane *plane = new shapes::Plane(boundingPlanes_[i * 4], boundingPlanes_[i * 4 + 1], boundingPlanes_[i * 4 + 2], boundingPlanes_[i * 4 + 3]);
00154 model->addObject("bounds", plane);
00155 ROS_INFO("Added static plane %fx + %fy + %fz + %f = 0 for model %p", boundingPlanes_[i * 4], boundingPlanes_[i * 4 + 1], boundingPlanes_[i * 4 + 2], boundingPlanes_[i * 4 + 3], model.get());
00156 }
00157
00158 model->unlock();
00159 }
00160
00161 void planning_environment::CollisionModels::loadParams(void)
00162 {
00163
00164 }
00165
00166 void planning_environment::CollisionModels::loadCollision(const std::vector<std::string> &links)
00167 {
00168
00169 boundingPlanes_.clear();
00170
00171 std::string planes;
00172 nh_.param<std::string>("bounding_planes", planes, std::string());
00173
00174 std::stringstream ss(planes);
00175 if (!planes.empty())
00176 while (ss.good() && !ss.eof())
00177 {
00178 double value;
00179 ss >> value;
00180 boundingPlanes_.push_back(value);
00181 }
00182 if (boundingPlanes_.size() % 4 != 0)
00183 {
00184 ROS_WARN("~bounding_planes must be a list of 4-tuples (a b c d) that define planes ax+by+cz+d=0");
00185 boundingPlanes_.resize(boundingPlanes_.size() - (boundingPlanes_.size() % 4));
00186 }
00187
00188 if (loadedModels())
00189 {
00190 ode_collision_model_ = boost::shared_ptr<collision_space::EnvironmentModel>(new collision_space::EnvironmentModelODE());
00191 setupModel(ode_collision_model_,links);
00192
00193
00194
00195 } else {
00196 ROS_WARN("Models not loaded");
00197 }
00198 }