Go to the documentation of this file.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 "collision_space/environment.h"
00038 #include <ros/console.h>
00039 #include <iomanip>
00040
00041 collision_space::EnvironmentModel::AllowedCollisionMatrix::AllowedCollisionMatrix(const std::vector<std::string>& names,
00042 bool allowed)
00043 {
00044 unsigned int ns = names.size();
00045 allowed_entries_.resize(ns);
00046 for(unsigned int i = 0; i < ns; i++) {
00047 allowed_entries_[i].resize(ns,allowed);
00048 allowed_entries_bimap_.insert(entry_type::value_type(names[i], i));
00049 }
00050 valid_ = true;
00051 }
00052
00053 collision_space::EnvironmentModel::AllowedCollisionMatrix::AllowedCollisionMatrix(const std::vector<std::vector<bool> >& all_coll_vectors,
00054 const std::map<std::string, unsigned int>& all_coll_indices)
00055 {
00056 unsigned int num_outer = all_coll_vectors.size();
00057 valid_ = true;
00058 if(all_coll_indices.size() != all_coll_vectors.size()) {
00059 valid_ = false;
00060 ROS_WARN_STREAM("Indices size " << all_coll_indices.size() << " not equal to num vecs " << all_coll_vectors.size());
00061 return;
00062 }
00063 for(std::map<std::string, unsigned int>::const_iterator it = all_coll_indices.begin();
00064 it != all_coll_indices.end();
00065 it++) {
00066 allowed_entries_bimap_.insert(entry_type::value_type(it->first, it->second));
00067 }
00068
00069 if(allowed_entries_bimap_.left.size() != all_coll_indices.size()) {
00070 valid_ = false;
00071 ROS_WARN_STREAM("Some strings or values in allowed collision matrix are repeated");
00072 }
00073 if(allowed_entries_bimap_.right.begin()->first != 0) {
00074 valid_ = false;
00075 ROS_WARN_STREAM("No entry with index 0 in map");
00076 }
00077 if(allowed_entries_bimap_.right.rbegin()->first != num_outer-1) {
00078 valid_ = false;
00079 ROS_WARN_STREAM("Last index should be " << num_outer << " but instead is " << allowed_entries_bimap_.right.rbegin()->first);
00080 }
00081
00082 for(unsigned int i = 0; i < num_outer; i++) {
00083 if(num_outer != all_coll_vectors[i].size()) {
00084 valid_ = false;
00085 ROS_WARN_STREAM("Entries size for " << allowed_entries_bimap_.right.at(i) << " is " << all_coll_vectors[i].size() << " instead of " << num_outer);
00086 }
00087 }
00088 allowed_entries_ = all_coll_vectors;
00089 }
00090
00091 collision_space::EnvironmentModel::AllowedCollisionMatrix::AllowedCollisionMatrix(const AllowedCollisionMatrix& acm)
00092 {
00093 valid_ = acm.valid_;
00094 allowed_entries_ = acm.allowed_entries_;
00095 allowed_entries_bimap_ = acm.allowed_entries_bimap_;
00096 }
00097
00098 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::getAllowedCollision(const std::string& name1,
00099 const std::string& name2,
00100 bool& allowed_collision) const
00101 {
00102 entry_type::left_const_iterator it1 = allowed_entries_bimap_.left.find(name1);
00103 if(it1 == allowed_entries_bimap_.left.end()) {
00104 return false;
00105 }
00106 entry_type::left_const_iterator it2 = allowed_entries_bimap_.left.find(name2);
00107 if(it2 == allowed_entries_bimap_.left.end()) {
00108 return false;
00109 }
00110 if(it1->second > allowed_entries_.size()) {
00111 ROS_INFO_STREAM("Something wrong with acm entry for " << name1);
00112 return false;
00113 }
00114 if(it2->second > allowed_entries_[it1->second].size()) {
00115 ROS_INFO_STREAM("Something wrong with acm entry for " << name2);
00116 return false;
00117 }
00118 allowed_collision = allowed_entries_[it1->second][it2->second];
00119 return true;
00120 }
00121
00122 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::getAllowedCollision(unsigned int i, unsigned int j,
00123 bool& allowed_collision) const
00124 {
00125 if(i > allowed_entries_.size() || j > allowed_entries_[i].size()) {
00126 return false;
00127 }
00128 allowed_collision = allowed_entries_[i][j];
00129 return true;
00130 }
00131
00132 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::hasEntry(const std::string& name) const
00133 {
00134 return(allowed_entries_bimap_.left.find(name) != allowed_entries_bimap_.left.end());
00135 }
00136
00137 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::getEntryIndex(const std::string& name,
00138 unsigned int& index) const
00139 {
00140 entry_type::left_const_iterator it1 = allowed_entries_bimap_.left.find(name);
00141 if(it1 == allowed_entries_bimap_.left.end()) {
00142 return false;
00143 }
00144 index = it1->second;
00145 return true;
00146 }
00147
00148 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::getEntryName(const unsigned int ind,
00149 std::string& name) const
00150 {
00151 entry_type::right_const_iterator it1 = allowed_entries_bimap_.right.find(ind);
00152 if(it1 == allowed_entries_bimap_.right.end()) {
00153 return false;
00154 }
00155 name = it1->second;
00156 return true;
00157 }
00158
00159 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::removeEntry(const std::string& name) {
00160 if(allowed_entries_bimap_.left.find(name) == allowed_entries_bimap_.left.end()) {
00161 return false;
00162 }
00163 unsigned int last_index = allowed_entries_bimap_.size()-1;
00164 unsigned int ind = allowed_entries_bimap_.left.find(name)->second;
00165 allowed_entries_.erase(allowed_entries_.begin()+ind);
00166 for(unsigned int i = 0; i < allowed_entries_.size(); i++) {
00167 allowed_entries_[i].erase(allowed_entries_[i].begin()+ind);
00168 }
00169 allowed_entries_bimap_.left.erase(name);
00170
00171 if(ind != last_index) {
00172
00173 entry_type::right_iterator it = allowed_entries_bimap_.right.find(last_index);
00174 if(it == allowed_entries_bimap_.right.end()) {
00175 ROS_INFO_STREAM("Something wrong with last index " << last_index << " ind " << ind);
00176 }
00177
00178 for(unsigned int i = ind+1; i <= last_index; i++) {
00179 entry_type::right_iterator it = allowed_entries_bimap_.right.find(i);
00180 if(it == allowed_entries_bimap_.right.end()) {
00181 ROS_WARN_STREAM("Problem in replace " << i);
00182 return false;
00183 }
00184 bool successful_replace = allowed_entries_bimap_.right.replace_key(it, i-1);
00185 if(!successful_replace) {
00186 ROS_WARN_STREAM("Can't replace");
00187 return false;
00188 }
00189 }
00190 }
00191 return true;
00192 }
00193
00194 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::addEntry(const std::string& name,
00195 bool allowed)
00196 {
00197 if(allowed_entries_bimap_.left.find(name) != allowed_entries_bimap_.left.end()) {
00198 return false;
00199 }
00200 unsigned int ind = allowed_entries_.size();
00201 allowed_entries_bimap_.insert(entry_type::value_type(name,ind));
00202 std::vector<bool> new_entry(ind+1, allowed);
00203 allowed_entries_.resize(ind+1);
00204 allowed_entries_[ind] = new_entry;
00205 for(unsigned int i = 0; i < ind; i++) {
00206 allowed_entries_[i].resize(ind+1);
00207 allowed_entries_[i][ind] = allowed;
00208 }
00209 return true;
00210 }
00211
00212 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(bool allowed)
00213 {
00214 for(unsigned int i = 0; i < allowed_entries_.size(); i++) {
00215 for(unsigned int j = 0; j < allowed_entries_[i].size(); j++) {
00216 allowed_entries_[i][j] = allowed;
00217 allowed_entries_[j][i] = allowed;
00218 }
00219 }
00220 return true;
00221 }
00222
00223 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(const std::string& name1,
00224 const std::string& name2,
00225 bool allowed) {
00226 entry_type::left_const_iterator it1 = allowed_entries_bimap_.left.find(name1);
00227 if(it1 == allowed_entries_bimap_.left.end()) {
00228 return false;
00229 }
00230 entry_type::left_const_iterator it2 = allowed_entries_bimap_.left.find(name2);
00231 if(it2 == allowed_entries_bimap_.left.end()) {
00232 return false;
00233 }
00234 allowed_entries_[it1->second][it2->second] = allowed;
00235 allowed_entries_[it2->second][it1->second] = allowed;
00236 return true;
00237 }
00238
00239 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(unsigned int i, unsigned int j,
00240 bool allowed)
00241 {
00242 if(i > allowed_entries_.size() || j > allowed_entries_[i].size()) {
00243 return false;
00244 }
00245 allowed_entries_[i][j] = allowed;
00246 allowed_entries_[j][i] = allowed;
00247 return true;
00248 }
00249 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(const std::string& name,
00250 bool allowed)
00251 {
00252 if(allowed_entries_bimap_.left.find(name) == allowed_entries_bimap_.left.end()) {
00253 return false;
00254 }
00255 unsigned int ind = allowed_entries_bimap_.left.find(name)->second;
00256 for(unsigned int i = 0; i < allowed_entries_.size(); i++) {
00257 allowed_entries_[i][ind] = allowed;
00258 allowed_entries_[ind][i] = allowed;
00259 }
00260 return true;
00261 }
00262
00263 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(const std::string& name,
00264 const std::vector<std::string>& change_names,
00265 bool allowed)
00266 {
00267 bool ok = true;
00268 if(allowed_entries_bimap_.left.find(name) == allowed_entries_bimap_.left.end()) {
00269 ROS_DEBUG_STREAM("No entry for " << name);
00270 ok = false;
00271 return ok;
00272 }
00273 unsigned int ind_1 = allowed_entries_bimap_.left.find(name)->second;
00274 for(unsigned int i = 0; i < change_names.size(); i++) {
00275 if(allowed_entries_bimap_.left.find(change_names[i]) == allowed_entries_bimap_.left.end()) {
00276 ROS_DEBUG_STREAM("No entry for " << change_names[i]);
00277 ok = false;
00278 continue;
00279 }
00280 unsigned int ind_2 = allowed_entries_bimap_.left.find(change_names[i])->second;
00281 if(ind_1 >= allowed_entries_.size()) {
00282 ROS_ERROR_STREAM("Got an index entry for name " << name << " ind " << ind_1 << " but only have "
00283 << allowed_entries_.size() << " in allowed collision matrix.");
00284 return false;
00285 }
00286 if(ind_2 >= allowed_entries_[ind_1].size()) {
00287 ROS_ERROR_STREAM("Got an index entry for name " << change_names[i] << " index " << ind_2 << " but only have " <<
00288 allowed_entries_[ind_1].size() << " in allowed collision matrix.");
00289 return false;
00290 }
00291 allowed_entries_[ind_1][ind_2] = allowed;
00292 allowed_entries_[ind_2][ind_1] = allowed;
00293 }
00294 return ok;
00295 }
00296
00297 bool collision_space::EnvironmentModel::AllowedCollisionMatrix::changeEntry(const std::vector<std::string>& change_names_1,
00298 const std::vector<std::string>& change_names_2,
00299 bool allowed)
00300 {
00301 bool ok = true;
00302 for(unsigned int i = 0; i < change_names_1.size(); i++) {
00303 if(!changeEntry(change_names_1[i], change_names_2, allowed)) {
00304 ok = false;
00305 }
00306 }
00307 return ok;
00308 }
00309
00310 void collision_space::EnvironmentModel::AllowedCollisionMatrix::getAllEntryNames(std::vector<std::string>& names) const
00311 {
00312 names.clear();
00313 for(entry_type::right_const_iterator it = allowed_entries_bimap_.right.begin(); it != allowed_entries_bimap_.right.end(); it++) {
00314 names.push_back(it->second);
00315 }
00316 }
00317
00318 void collision_space::EnvironmentModel::AllowedCollisionMatrix::print(std::ostream& out) const {
00319 for(entry_type::right_const_iterator it = allowed_entries_bimap_.right.begin(); it != allowed_entries_bimap_.right.end(); it++) {
00320 out << std::setw(40) << it->second;
00321 out << " | ";
00322 for(entry_type::right_const_iterator it2 = allowed_entries_bimap_.right.begin(); it2 != allowed_entries_bimap_.right.end(); it2++) {
00323 out << std::setw(3) << allowed_entries_[it->first][it2->first];
00324 }
00325 out << std::endl;
00326 }
00327 }
00328
00329 bool collision_space::EnvironmentModel::getVerbose(void) const
00330 {
00331 return verbose_;
00332 }
00333
00334 void collision_space::EnvironmentModel::setVerbose(bool verbose)
00335 {
00336 verbose_ = verbose;
00337 }
00338
00339 const collision_space::EnvironmentObjects* collision_space::EnvironmentModel::getObjects(void) const
00340 {
00341 return objects_;
00342 }
00343
00344 const planning_models::KinematicModel* collision_space::EnvironmentModel::getRobotModel(void) const
00345 {
00346 return robot_model_;
00347 }
00348
00349 double collision_space::EnvironmentModel::getRobotScale(void) const
00350 {
00351 return robot_scale_;
00352 }
00353
00354 double collision_space::EnvironmentModel::getRobotPadding(void) const
00355 {
00356 return default_robot_padding_;
00357 }
00358
00359 void collision_space::EnvironmentModel::setRobotModel(const planning_models::KinematicModel* model,
00360 const AllowedCollisionMatrix& acm,
00361 const std::map<std::string, double>& link_padding_map,
00362 double default_padding,
00363 double scale)
00364 {
00365 robot_model_ = model;
00366 default_collision_matrix_ = acm;
00367 robot_scale_ = scale;
00368 default_robot_padding_ = default_padding;
00369 default_link_padding_map_ = link_padding_map;
00370 }
00371
00372 void collision_space::EnvironmentModel::lock(void) const
00373 {
00374 lock_.lock();
00375 }
00376
00377 void collision_space::EnvironmentModel::unlock(void) const
00378 {
00379 lock_.unlock();
00380 }
00381
00382 const collision_space::EnvironmentModel::AllowedCollisionMatrix&
00383 collision_space::EnvironmentModel::getDefaultAllowedCollisionMatrix() const
00384 {
00385 return default_collision_matrix_;
00386 }
00387
00388 const collision_space::EnvironmentModel::AllowedCollisionMatrix&
00389 collision_space::EnvironmentModel::getCurrentAllowedCollisionMatrix() const {
00390 if(use_altered_collision_matrix_) {
00391 return altered_collision_matrix_;
00392 }
00393 return default_collision_matrix_;
00394 }
00395
00396 void collision_space::EnvironmentModel::setAlteredCollisionMatrix(const AllowedCollisionMatrix& acm) {
00397 use_altered_collision_matrix_ = true;
00398 altered_collision_matrix_ = acm;
00399 }
00400
00401 void collision_space::EnvironmentModel::revertAlteredCollisionMatrix() {
00402 use_altered_collision_matrix_ = false;
00403 }
00404
00405 void collision_space::EnvironmentModel::setAlteredLinkPadding(const std::map<std::string, double>& new_link_padding) {
00406 altered_link_padding_map_.clear();
00407 for(std::map<std::string, double>::const_iterator it = new_link_padding.begin();
00408 it != new_link_padding.end();
00409 it++) {
00410 if(default_link_padding_map_.find(it->first) == default_link_padding_map_.end()) {
00411
00412 continue;
00413 }
00414
00415 if(default_link_padding_map_.find(it->first)->second != it->second) {
00416 altered_link_padding_map_[it->first] = it->second;
00417 }
00418 }
00419 use_altered_link_padding_map_ = true;
00420 }
00421
00422 void collision_space::EnvironmentModel::revertAlteredLinkPadding() {
00423 altered_link_padding_map_.clear();
00424 use_altered_link_padding_map_ = false;
00425 }
00426
00427 const std::map<std::string, double>& collision_space::EnvironmentModel::getDefaultLinkPaddingMap() const {
00428 return default_link_padding_map_;
00429 }
00430
00431 std::map<std::string, double> collision_space::EnvironmentModel::getCurrentLinkPaddingMap() const {
00432 std::map<std::string, double> ret_map = default_link_padding_map_;
00433 for(std::map<std::string, double>::const_iterator it = altered_link_padding_map_.begin();
00434 it != altered_link_padding_map_.end();
00435 it++) {
00436 ret_map[it->first] = it->second;
00437 }
00438 return ret_map;
00439 }
00440
00441 double collision_space::EnvironmentModel::getCurrentLinkPadding(std::string name) const {
00442 if(altered_link_padding_map_.find(name) != altered_link_padding_map_.end()) {
00443 return altered_link_padding_map_.find(name)->second;
00444 } else if(default_link_padding_map_.find(name) != default_link_padding_map_.end()) {
00445 return default_link_padding_map_.find(name)->second;
00446 }
00447 return 0.0;
00448 }
00449
00450 void collision_space::EnvironmentModel::setAllowedContacts(const std::vector<AllowedContact>& allowed_contacts)
00451 {
00452 allowed_contact_map_.clear();
00453 allowed_contacts_ = allowed_contacts;
00454 for(unsigned int i = 0; i < allowed_contacts.size(); i++) {
00455 allowed_contact_map_[allowed_contacts_[i].body_name_1][allowed_contacts_[i].body_name_2].push_back(allowed_contacts_[i]);
00456 allowed_contact_map_[allowed_contacts_[i].body_name_2][allowed_contacts_[i].body_name_1].push_back(allowed_contacts_[i]);
00457 }
00458 }
00459
00460 const std::vector<collision_space::EnvironmentModel::AllowedContact>& collision_space::EnvironmentModel::getAllowedContacts() const {
00461 return allowed_contacts_;
00462 }