38 #include <rclcpp/logger.hpp>
39 #include <rclcpp/logging.hpp>
60 for (std::size_t i = 0; i < names.size(); ++i)
62 for (std::size_t j = i; j < names.size(); ++j)
63 setEntry(names[i], names[j], allowed);
70 for (
const std::string&
name : srdf.getNoDefaultCollisionLinks())
73 for (
const auto& collision : srdf.getEnabledCollisionPairs())
74 setEntry(collision.link1_, collision.link2_,
false);
76 for (
const auto& collision : srdf.getDisabledCollisionPairs())
77 setEntry(collision.link1_, collision.link2_,
true);
82 if (msg.entry_names.size() != msg.entry_values.size() ||
83 msg.default_entry_names.size() != msg.default_entry_values.size())
86 "The number of links does not match the number of entries in AllowedCollisionMatrix message");
89 for (std::size_t i = 0; i < msg.default_entry_names.size(); ++i)
91 setDefaultEntry(msg.default_entry_names[i], msg.default_entry_values[i]);
94 for (std::size_t i = 0; i < msg.entry_names.size(); ++i)
96 if (msg.entry_values[i].enabled.size() != msg.entry_names.size())
98 RCLCPP_ERROR(
getLogger(),
"Number of entries is incorrect for link '%s' in AllowedCollisionMatrix message",
99 msg.entry_names[i].c_str());
102 for (std::size_t j = i + 1; j < msg.entry_values[i].enabled.size(); ++j)
105 if (!
getDefaultEntry(msg.entry_names[i], msg.entry_names[j], allowed_default))
109 if (allowed_entry != allowed_default)
110 setEntry(msg.entry_names[i], msg.entry_names[j], allowed_entry);
117 const auto it1 = allowed_contacts_.find(name1);
118 if (it1 == allowed_contacts_.end())
120 const auto it2 = it1->second.find(name2);
121 if (it2 == it1->second.end())
130 const auto it1 = entries_.find(name1);
131 if (it1 == entries_.end())
133 auto it2 = it1->second.find(name2);
134 if (it2 == it1->second.end())
136 allowed_collision = it2->second;
142 return entries_.find(
name) != entries_.end();
147 const auto it1 = entries_.find(name1);
148 if (it1 == entries_.end())
150 const auto it2 = it1->second.find(name2);
151 return it2 != it1->second.end();
157 entries_[name1][name2] = entries_[name2][name1] = v;
160 auto it = allowed_contacts_.find(name1);
161 if (it != allowed_contacts_.end())
163 auto jt = it->second.find(name2);
164 if (jt != it->second.end())
165 it->second.erase(jt);
167 it = allowed_contacts_.find(name2);
168 if (it != allowed_contacts_.end())
170 auto jt = it->second.find(name1);
171 if (jt != it->second.end())
172 it->second.erase(jt);
179 allowed_contacts_[name1][name2] = allowed_contacts_[name2][name1] = fn;
184 entries_.erase(
name);
185 allowed_contacts_.erase(
name);
186 for (
auto& entry : entries_)
187 entry.second.erase(
name);
188 for (
auto& allowed_contact : allowed_contacts_)
189 allowed_contact.second.erase(
name);
194 auto jt = entries_.find(name1);
195 if (jt != entries_.end())
197 auto it = jt->second.find(name2);
198 if (it != jt->second.end())
199 jt->second.erase(it);
201 jt = entries_.find(name2);
202 if (jt != entries_.end())
204 auto it = jt->second.find(name1);
205 if (it != jt->second.end())
206 jt->second.erase(it);
209 auto it = allowed_contacts_.find(name1);
210 if (it != allowed_contacts_.end())
212 auto jt = it->second.find(name2);
213 if (jt != it->second.end())
214 it->second.erase(jt);
216 it = allowed_contacts_.find(name2);
217 if (it != allowed_contacts_.end())
219 auto jt = it->second.find(name1);
220 if (jt != it->second.end())
221 it->second.erase(jt);
228 for (
const auto& other_name : other_names)
230 if (other_name !=
name)
238 for (
const auto& name1 : names1)
244 std::string last =
name;
245 for (
auto& entry : entries_)
247 if (
name != entry.first && last != entry.first)
258 for (
auto& entry : entries_)
260 for (
auto& it2 : entry.second)
268 default_entries_[
name] = v;
269 default_allowed_contacts_.erase(
name);
275 default_allowed_contacts_[
name] = fn;
280 auto it = default_entries_.find(
name);
281 if (it == default_entries_.end())
283 allowed_collision = it->second;
289 auto it = default_allowed_contacts_.find(
name);
290 if (it == default_allowed_contacts_.end())
298 return f1(contact) && f2(contact);
304 const bool found =
getEntry(name1, name2, fn);
310 if (found1 && !found2)
314 else if (!found1 && found2)
318 else if (found1 && found2)
320 fn = [fn1, fn2](
Contact& contact) {
return andDecideContact(fn1, fn2, contact); };
336 if (!found1 && !found2)
340 else if (found1 && !found2)
342 allowed_collision = t1;
344 else if (!found1 && found2)
346 allowed_collision = t2;
348 else if (found1 && found2)
375 allowed_contacts_.clear();
376 default_entries_.clear();
377 default_allowed_contacts_.clear();
383 for (
const auto& entry : entries_)
384 names.push_back(entry.first);
386 for (
const auto& item : default_entries_)
388 auto it = std::lower_bound(names.begin(), names.end(), item.first);
389 if (it != names.end() && *it != item.first)
390 names.insert(it, item.first);
396 msg.entry_names.clear();
397 msg.entry_values.clear();
398 msg.default_entry_names.clear();
399 msg.default_entry_values.clear();
403 msg.entry_values.resize(msg.entry_names.size());
404 for (std::size_t i = 0; i < msg.entry_names.size(); ++i)
405 msg.entry_values[i].enabled.resize(msg.entry_names.size(),
false);
409 for (std::size_t i = 0; i < msg.entry_names.size(); ++i)
415 msg.default_entry_names.push_back(msg.entry_names[i]);
419 for (std::size_t j = i; j < msg.entry_names.size(); ++j)
430 std::vector<std::string> names;
433 std::size_t spacing = 4;
434 for (
const auto&
name : names)
436 const std::size_t length =
name.length();
437 if (length > spacing)
442 std::size_t number_digits = 2;
443 while (names.size() > pow(10, number_digits) - 1)
447 for (std::size_t j = 0; j < number_digits; ++j)
449 out << std::setw(spacing + number_digits + 8) <<
"";
450 for (std::size_t i = 0; i < names.size(); ++i)
452 std::stringstream ss;
453 ss << std::setw(number_digits) << i;
454 out << std::setw(3) << ss.str().c_str()[j];
459 const char* indicator =
"01?";
460 for (std::size_t i = 0; i < names.size(); ++i)
462 out << std::setw(spacing) << names[i];
463 out << std::setw(number_digits + 1) << i;
469 out << indicator[type];
477 for (std::size_t j = 0; j < names.size(); ++j)
482 out << std::setw(3) << indicator[type];
486 out << std::setw(3) <<
'-';
void getAllEntryNames(std::vector< std::string > &names) const
Get all the names known to the collision matrix.
void clear()
Clear the allowed collision matrix.
void setEntry(const std::string &name1, const std::string &name2, bool allowed)
Set an entry corresponding to a pair of elements.
bool getEntry(const std::string &name1, const std::string &name2, AllowedCollision::Type &allowed_collision_type) const
Get the type of the allowed collision between two elements. Return true if the entry is included in t...
bool getAllowedCollision(const std::string &name1, const std::string &name2, DecideContactFn &fn) const
Get the allowed collision predicate between two elements. Return true if a predicate for entry is inc...
void print(std::ostream &out) const
Print the allowed collision matrix.
void setDefaultEntry(const std::string &name, bool allowed)
Set the default value for entries that include name but are not set explicitly with setEntry().
void removeEntry(const std::string &name1, const std::string &name2)
Remove an entry corresponding to a pair of elements. Nothing happens if the pair does not exist in th...
bool getDefaultEntry(const std::string &name, AllowedCollision::Type &allowed_collision) const
Get the type of the allowed collision to be considered by default for an element. Return true if a de...
bool hasEntry(const std::string &name) const
Check if the allowed collision matrix has an entry at all for an element. Returns true if the element...
void getMessage(moveit_msgs::msg::AllowedCollisionMatrix &msg) const
Get the allowed collision matrix as a message.
@ CONDITIONAL
The collision is allowed depending on a predicate evaluated on the produced contact....
@ NEVER
Collisions between the pair of bodies is never ok, i.e., if two bodies are in contact in a particular...
@ ALWAYS
Collisions between a particular pair of bodies does not imply that the robot configuration is in coll...
rclcpp::Logger getLogger()
std::function< bool(collision_detection::Contact &)> DecideContactFn
Signature of predicate that decides whether a contact is allowed or not (when AllowedCollision::Type ...
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.