38 distance = std::numeric_limits<double>::max();
43 transform[0] = Eigen::Isometry3d::Identity();
44 transform[1] = Eigen::Isometry3d::Identity();
107 auto& cv =
data_[key];
108 return cv.emplace_back(std::move(result));
113 assert(!results.empty());
115 count_ +=
static_cast<long>(results.size());
116 auto& cv =
data_[key];
117 cv.reserve(cv.size() + results.size());
118 cv.insert(cv.end(), results.begin(), results.end());
125 auto& cv =
data_[key];
126 count_ += (1 -
static_cast<long>(cv.size()));
130 return cv.emplace_back(std::move(result));
136 assert(!results.empty());
137 auto& cv =
data_[key];
138 count_ += (
static_cast<long>(results.size()) -
static_cast<long>(cv.size()));
141 cv.reserve(results.size());
142 cv.insert(cv.end(), results.begin(), results.end());
147 long sub_segment_index,
148 long sub_segment_last_index,
149 const std::vector<std::string>& active_link_names,
154 for (
auto& pair : sub_segment_results.
data_)
158 for (
auto&
r : pair.second)
161 for (
size_t j = 0; j < 2; ++j)
163 if (std::find(active_link_names.begin(), active_link_names.end(),
r.link_names[j]) != active_link_names.end())
165 r.cc_time[j] = (
r.cc_time[j] < 0) ?
166 (
static_cast<double>(sub_segment_index) * segment_dt) :
167 (
static_cast<double>(sub_segment_index) * segment_dt) + (
r.cc_time[j] * segment_dt);
168 assert(
r.cc_time[j] >= 0.0 &&
r.cc_time[j] <= 1.0);
169 if (sub_segment_index == 0 &&
172 else if (sub_segment_index == sub_segment_last_index &&
180 r.cc_transform =
r.transform;
189 if (!pair.second.empty())
192 count_ +=
static_cast<long>(pair.second.size());
193 auto it =
data_.find(pair.first);
194 if (it ==
data_.end())
200 assert(it !=
data_.end());
205 it->second.reserve(it->second.size() + pair.second.size());
206 it->second.insert(it->second.end(), pair.second.begin(), pair.second.end());
219 std::size_t cnt{ 0 };
220 for (
const auto& pair :
data_)
222 if (!pair.second.empty())
237 for (
auto& cv :
data_)
246 for (
auto it =
data_.cbegin(); it !=
data_.cend();)
247 it = it->second.empty() ?
data_.erase(it) : std::next(it);
273 v.reserve(
static_cast<std::size_t
>(
count_));
274 for (
auto& mv :
data_)
276 std::move(mv.second.begin(), mv.second.end(), std::back_inserter(v));
285 v.reserve(
static_cast<std::size_t
>(
count_));
286 for (
const auto& mv :
data_)
287 std::copy(mv.second.begin(), mv.second.end(), std::back_inserter(v));
293 v.reserve(
static_cast<std::size_t
>(
count_));
294 for (
auto& mv :
data_)
295 v.insert(v.end(), mv.second.begin(), mv.second.end());
301 v.reserve(
static_cast<std::size_t
>(
count_));
302 for (
const auto& mv :
data_)
303 v.insert(v.end(), mv.second.begin(), mv.second.end());
308 std::size_t removed_cnt{ 0 };
309 for (
auto& pair :
data_)
311 std::size_t current_cnt = pair.second.size();
313 removed_cnt += (current_cnt - pair.second.size());
315 count_ -=
static_cast<long>(removed_cnt);
327 std::stringstream ss;
328 std::map<KeyType, std::size_t> collision_counts;
329 std::map<KeyType, double> closest_distances;
332 for (
const auto& pair :
data_)
334 if (!pair.second.empty())
336 collision_counts[pair.first] = pair.second.size();
337 closest_distances[pair.first] = std::numeric_limits<double>::max();
340 for (
const auto& result : pair.second)
342 closest_distances[pair.first] = std::min(closest_distances[pair.first], result.distance);
347 if (collision_counts.empty())
349 return "No collisions detected";
352 auto max_element = std::max_element(collision_counts.begin(),
353 collision_counts.end(),
354 [](
const auto& p1,
const auto& p2) { return p1.second < p2.second; });
356 ss << max_element->first.first <<
" - " << max_element->first.second <<
": " << max_element->second
357 <<
" collisions, min dist: " << closest_distances[max_element->first];
364 std::shared_ptr<const tesseract_common::ContactAllowedValidator> validator,
368 , collision_margin_data(std::move(collision_margin_data))
369 , validator(std::move(validator))
370 , req(std::move(req))
399 throw std::runtime_error(
"ContactManagerConfig, pair margin override type is NONE but pair collision margins "
403 throw std::runtime_error(
"ContactManagerConfig, acm override type is NONE but allowed collision entries exist!");
412 ret_val &= (
acm == rhs.
acm);
421 double longest_valid_segment_length,
423 : contact_request(std::move(request))
425 , longest_valid_segment_length(longest_valid_segment_length)
426 , check_program_mode(check_program_mode)
443 const Eigen::VectorXd& start_state,
444 const Eigen::VectorXd& end_state)
445 : substep(substep_number), state0(start_state), state1(end_state)
450 : substep(substep_number), state0(state), state1(state)
459 double worst_distance = std::numeric_limits<double>::max();
460 for (
const auto& collision :
contacts)
463 if (!collision.second.empty() && collision.second.front().distance < worst_distance)
465 worst_distance = collision.second.front().distance;
466 worst_collision = collision.second;
469 return worst_collision;
473 const Eigen::VectorXd& start_state,
474 const Eigen::VectorXd& end_state,
476 : step(step_number), state0(start_state), state1(end_state), total_substeps(num_substeps)
478 substeps.resize(
static_cast<std::size_t
>(num_substeps));
482 : step(step_number), state0(state), state1(state), total_substeps(2)
484 substeps.resize(
static_cast<std::size_t
>(2));
490 substeps.resize(
static_cast<std::size_t
>(num_substeps));
497 int num_contacts = 0;
498 for (
const auto& substep :
substeps)
499 num_contacts += substep.numContacts();
506 double worst_distance = std::numeric_limits<double>::max();
507 for (
const auto& substep :
substeps)
511 if (!substep_worst_collision.empty() && substep_worst_collision.front().distance < worst_distance)
513 worst_distance = substep_worst_collision.front().distance;
514 worst_substep = substep;
517 return worst_substep;
530 int most_contacts = 0;
532 for (
const auto& substep :
substeps)
536 if (current_contacts > most_contacts)
538 most_contacts = current_contacts;
539 most_collisions_substep = substep;
542 return most_collisions_substep;
550 : joint_names(std::move(j_names)), total_steps(num_steps)
552 steps.resize(
static_cast<std::size_t
>(num_steps));
558 steps.resize(
static_cast<std::size_t
>(num_steps));
565 int num_contacts = 0;
566 for (
const auto& step :
steps)
567 num_contacts += step.numContacts();
574 double worst_distance = std::numeric_limits<double>::max();
575 for (
const auto& step :
steps)
578 if (!step_worst_collision.empty() && step_worst_collision.front().distance < worst_distance)
580 worst_distance = step_worst_collision.front().distance;
590 return worst_collision;
595 int most_contacts = 0;
597 for (
const auto& step :
steps)
601 if (current_contacts > most_contacts)
603 most_contacts = current_contacts;
604 most_collisions_step = step;
607 return most_collisions_step;
619 std::stringstream ss;
623 ss <<
"No contacts detected\n";
627 int step_details_width = 0;
628 int substep_details_width = 0;
632 std::string step_title =
"STEP";
633 int longest_steps_width = 2 +
static_cast<int>(step_title.size());
634 int number_steps_digits =
static_cast<int>(std::log10(
steps.back().step)) + 1;
636 int width_steps_display = (number_steps_digits * 2) + 3;
637 longest_steps_width = std::max(width_steps_display, longest_steps_width);
639 step_details_width += longest_steps_width;
642 std::string joint_name_title =
"JOINT NAMES";
643 int longest_joint_name_width =
static_cast<int>(joint_name_title.size()) + 2;
645 longest_joint_name_width = std::max(
static_cast<int>(
name.size()) + 2, longest_joint_name_width);
647 step_details_width += longest_joint_name_width;
651 std::string state0_title =
"STATE0";
652 std::string state1_title =
"STATE1";
653 int longest_state0_width = 9;
654 int longest_state1_width = 9;
655 for (
const auto& step :
steps)
657 for (
int i = 0; i < static_cast<int>(step.state0.size()); i++)
659 double state0_value = step.state0(i);
660 if (state0_value < 0)
664 int state0_number_digits_left_decimal =
static_cast<int>(std::log10(state0_value)) + 1;
666 longest_state0_width = std::max(state0_number_digits_left_decimal + 7, longest_state0_width);
668 double state1_value = step.state1(i);
669 if (state1_value < 0)
673 int state1_number_digits_left_decimal =
static_cast<int>(std::log10(state1_value)) + 1;
675 longest_state1_width = std::max(state1_number_digits_left_decimal + 7, longest_state1_width);
679 step_details_width += longest_state0_width;
680 step_details_width += longest_state1_width;
683 std::string substep_title =
"SUBSTEP";
684 int longest_substep_width = 2 +
static_cast<int>(substep_title.size());
685 for (
const auto& step :
steps)
688 if (step.numSubsteps() == 0)
693 int number_digits =
static_cast<int>(std::log10(step.substeps.size())) + 1;
694 int width = (2 * number_digits) + 3;
695 longest_substep_width = std::max(width, longest_substep_width);
698 substep_details_width += longest_substep_width;
701 std::string link1_title =
"LINK1";
702 std::string link2_title =
"LINK2";
703 int longest_link1_width =
static_cast<int>(link1_title.size()) + 2;
704 int longest_link2_width =
static_cast<int>(link2_title.size()) + 2;
705 for (
const auto& step :
steps)
707 for (
const auto& substep : step.substeps)
709 if (!substep.contacts.empty())
711 for (
const auto& collision : substep.contacts)
713 if (collision.second.empty())
715 std::string link1_name = collision.second.front().link_names[0];
716 longest_link1_width = std::max(
static_cast<int>(link1_name.size()) + 2, longest_link1_width);
718 std::string link2_name = collision.second.front().link_names[1];
719 longest_link2_width = std::max(
static_cast<int>(link2_name.size()) + 2, longest_link2_width);
725 substep_details_width += longest_link1_width;
726 substep_details_width += longest_link2_width;
731 std::string distance_title =
"DISTANCE";
732 int longest_distance_width =
static_cast<int>(distance_title.size()) + 2;
734 substep_details_width += longest_distance_width;
737 std::string new_step_string(
static_cast<std::size_t
>(step_details_width),
'*');
738 new_step_string +=
"|";
739 new_step_string += std::string(
static_cast<std::size_t
>(substep_details_width),
'*');
740 std::string new_substep_string(
static_cast<std::size_t
>(substep_details_width),
'-');
746 ss << std::setw(longest_steps_width) << step_title << std::setw(longest_joint_name_width) << joint_name_title
747 << std::setw(longest_state0_width) << state0_title << std::setw(longest_state1_width) << state1_title <<
"|"
748 << std::setw(longest_substep_width) << substep_title << std::setw(longest_link1_width) << link1_title
749 << std::setw(longest_link2_width) << link2_title << std::setw(longest_distance_width) << distance_title <<
"\n";
751 ss << new_step_string <<
"\n";
753 for (
const auto& step :
steps)
756 if (step.numContacts() == 0)
760 std::string step_number_string = std::to_string(step.step) +
"/" + std::to_string(
total_steps);
762 for (
const auto& substep : step.substeps)
764 if (substep.contacts.empty())
768 if (substep.numContacts() == 0)
772 std::string substep_string = std::to_string(substep.substep) +
"/" + std::to_string(step.total_substeps);
775 for (
const auto& collision : substep.contacts)
777 if (collision.second.empty())
780 ss << std::setw(longest_steps_width) << step_number_string;
783 if (line_number <
static_cast<int>(
joint_names.size()))
785 ss << std::setprecision(4) << std::fixed;
786 ss << std::setw(longest_joint_name_width) << joint_names[static_cast<std::size_t>(line_number)];
787 ss << std::setw(longest_state0_width) << step.state0(line_number);
788 ss << std::setw(longest_state1_width) << step.state1(line_number);
793 ss << std::setw(longest_joint_name_width) <<
" " << std::setw(longest_state0_width) <<
" "
794 << std::setw(longest_state1_width) <<
" ";
800 ss << std::setw(longest_substep_width) << substep_string;
801 ss << std::setw(longest_link1_width) << collision.second.front().link_names[0];
802 ss << std::setw(longest_link2_width) << collision.second.front().link_names[1];
803 ss << std::setw(longest_distance_width) << collision.second.front().distance;
809 ss << std::setw(longest_steps_width) << step_number_string;
810 if (line_number <
static_cast<int>(
joint_names.size()))
812 ss << std::setw(longest_joint_name_width) << joint_names[static_cast<std::size_t>(line_number)];
813 ss << std::setw(longest_state0_width) << step.state0(line_number);
814 ss << std::setw(longest_state1_width) << step.state1(line_number);
818 ss << std::setw(longest_joint_name_width) <<
" " << std::setw(longest_state0_width) <<
" "
819 << std::setw(longest_state1_width) <<
" ";
822 ss << new_substep_string;
828 while (line_number <
static_cast<int>(
joint_names.size()))
830 ss << std::setw(longest_steps_width) << step_number_string;
831 ss << std::setw(longest_joint_name_width) << joint_names[static_cast<std::size_t>(line_number)];
832 ss << std::setw(longest_state0_width) << step.state0(line_number);
833 ss << std::setw(longest_state1_width) << step.state1(line_number);
837 ss << new_step_string <<
"\n";
845 std::unordered_map<std::string, std::size_t> link_index_map;
846 std::size_t index = 0;
847 for (
const auto& step :
steps)
849 for (
const auto& substep : step.substeps)
851 for (
const auto& contact_pair : substep.contacts.getContainer())
853 const auto& link_pair = contact_pair.first;
854 if (link_index_map.find(link_pair.first) == link_index_map.end())
856 link_index_map[link_pair.first] = index++;
858 if (link_index_map.find(link_pair.second) == link_index_map.end())
860 link_index_map[link_pair.second] = index++;
867 std::size_t size = link_index_map.size();
868 std::vector<std::vector<int>> collision_matrix(size, std::vector<int>(size, 0));
871 for (
const auto& step :
steps)
873 for (
const auto& substep : step.substeps)
875 for (
const auto& contact_pair : substep.contacts.getContainer())
877 const auto& link_pair = contact_pair.first;
878 std::size_t row = link_index_map[link_pair.first];
879 std::size_t col = link_index_map[link_pair.second];
880 collision_matrix[row][col]++;
881 collision_matrix[col][row]++;
887 std::stringstream ss;
889 if (link_index_map.empty())
891 ss <<
"No contacts detected\n";
896 std::size_t max_link_name_length = 0;
897 for (
const auto& entry : link_index_map)
898 max_link_name_length = std::max(entry.first.size(), max_link_name_length);
901 const int column_width =
static_cast<int>(max_link_name_length) + 2;
904 ss << std::setw(column_width + 5) <<
" "
906 for (std::size_t i = 0; i < link_index_map.size(); ++i)
908 ss << std::setw(5) << i <<
"|";
913 ss << std::setw(column_width + 5) <<
" "
915 for (std::size_t i = 0; i < link_index_map.size(); ++i)
917 ss << std::setw(5) <<
"-----"
923 std::vector<std::string> link_names(link_index_map.size());
924 for (
const auto& entry : link_index_map)
926 link_names[entry.second] = entry.first;
929 for (std::size_t i = 0; i < link_names.size(); ++i)
931 ss << std::setw(5) << i << std::setw(column_width) << link_names[i] <<
"|";
932 for (std::size_t j = 0; j < link_names.size(); ++j)
937 ss << std::setw(5) << collision_matrix[i][j] <<
"|";