28 #include <RobotAPI/interface/core/PoseBase.h>
40 m_only_submit_first_n_results(-1),
41 m_max_distance_to_put_together(100),
42 m_max_yaw_difference(
M_PI / 4),
43 m_periodic_task_interval(500),
44 m_accept_lines_after(100)
52 m_last_accepted_lines = IceUtil::Time::now();
60 &LaserScannerObstacleDetection::eval_obstacles, m_periodic_task_interval);
61 m_eval_obstacles->start();
68 m_eval_obstacles->stop();
78 LaserScannerObstacleDetection::get_distance_from_point_to_line_segment(
const Eigen::Vector2f& start,
const Eigen::Vector2f& end,
const Eigen::Vector2f& p)
const
81 const Eigen::Vector2f&
v = start;
82 const Eigen::Vector2f& w = end;
83 const Eigen::Vector2f vp = p -
v;
84 const Eigen::Vector2f vw = w -
v;
85 const float line_length_sq = vw(0) * vw(0) + vw(1) * vw(1);
88 if (line_length_sq == 0.0)
99 const float pv_dot_wv = vp(0) * vw(0) + vp(1) * vw(1);
101 const Eigen::Vector2f projection =
v + (t * vw);
108 LaserScannerObstacleDetection::get_angle_between_vectors(
const Eigen::Vector2f& v1,
const Eigen::Vector2f& v2)
const
111 const Eigen::Vector2f v1_vec_normed = v1.normalized();
112 const Eigen::Vector2f v2_vec_normed = v2.normalized();
113 const float dot_product_vec = v1_vec_normed(0) * v2_vec_normed(0) + v1_vec_normed(1) * v2_vec_normed(1);
114 float yaw = acos(dot_product_vec);
125 LaserScannerObstacleDetection::eval_obstacles()
130 std::unique_lock l{m_lines_buffer_mutex};
131 lines = m_lines_buffer;
132 m_lines_buffer.clear();
135 if (lines.empty() || m_only_submit_first_n_results == 0)
140 bool update_found =
false;
141 int lines_before = lines.size();
145 update_found =
false;
146 if (lines.size() < 2)
152 unsigned int remove1 = 0;
153 unsigned int remove2 = 0;
231 lines.erase(lines.begin() + remove2);
232 lines.erase(lines.begin() + remove1);
235 while (update_found);
237 ARMARX_DEBUG <<
"Finished updating the " << lines_before <<
" lines. Now we have " << lines.size() <<
" lines. The operation took " << (IceUtil::Time::now() - started).toMilliSeconds() <<
"ms";
240 std::vector<dynamicobstaclemanager::LineSegment> converted_lines;
241 for (
const auto& chain : lines)
244 if (chain.size() < 2)
249 for (
auto it = chain.begin(); it != chain.end() - 1; it++)
251 converted_lines.emplace_back(dynamicobstaclemanager::LineSegment{*it, *(it + 1)});
254 m_obstacle_manager->add_decayable_line_segments(converted_lines);
258 if (m_only_submit_first_n_results > 0)
260 m_only_submit_first_n_results--;
292 std::lock_guard l{m_enabled_mutex};
300 std::lock_guard l{m_enabled_mutex};
308 std::lock_guard l{m_enabled_mutex};
325 defs->component(m_obstacle_manager,
"DynamicObstacleManager",
"ObstacleManager",
"The name of the obstacle manager proxy");
326 defs->topic<LaserScannerFeaturesListener>();
328 defs->optional(m_only_submit_first_n_results,
"SubmitOnlyFirstNResults",
"Only send the first laser scanner result. -1 for all.");
329 defs->optional(m_max_distance_to_put_together,
"MaxDistanceOfLinesToGroup",
"Max distance in mm of two lines to put them together");
330 defs->optional(m_max_yaw_difference,
"MaxAngleDifferenceOfLinesToGroup",
"Max angle difference in yaw of two lines to put them together");
331 defs->optional(m_periodic_task_interval,
"UpdateInterval",
"The interval to check the obstacles");
332 defs->optional(m_accept_lines_after,
"AcceptLinesAfter",
"Accept new Lines for buffer every x ms");
333 defs->optional(m_enabled,
"ActivateOnStartup",
"Activate the component on startup.");
341 std::lock_guard l{m_enabled_mutex};
342 if (! m_enabled or globalLineSegmentChains.empty())
348 if ((IceUtil::Time::now() - m_last_accepted_lines).toMilliSeconds() > m_accept_lines_after)
350 std::unique_lock l{m_lines_buffer_mutex};
353 ARMARX_DEBUG <<
"Got " << globalLineSegmentChains.size() <<
" new extracted edges to buffer.";
355 m_lines_buffer.insert(m_lines_buffer.end(), globalLineSegmentChains.begin(), globalLineSegmentChains.end());
356 m_last_accepted_lines = IceUtil::Time::now();