29 #include <RobotAPI/interface/core/PoseBase.h>
39 m_only_submit_first_n_results(-1),
40 m_max_distance_to_put_together(100),
41 m_max_yaw_difference(
M_PI / 4),
42 m_periodic_task_interval(500),
43 m_accept_lines_after(100)
50 m_last_accepted_lines = IceUtil::Time::now();
57 this, &LaserScannerObstacleDetection::eval_obstacles, m_periodic_task_interval);
58 m_eval_obstacles->start();
64 m_eval_obstacles->stop();
73 LaserScannerObstacleDetection::get_distance_from_point_to_line_segment(
74 const Eigen::Vector2f& start,
75 const Eigen::Vector2f& end,
76 const Eigen::Vector2f& p)
const
79 const Eigen::Vector2f&
v = start;
80 const Eigen::Vector2f& w = end;
81 const Eigen::Vector2f vp = p -
v;
82 const Eigen::Vector2f vw = w -
v;
83 const float line_length_sq = vw(0) * vw(0) + vw(1) * vw(1);
86 if (line_length_sq == 0.0)
97 const float pv_dot_wv = vp(0) * vw(0) + vp(1) * vw(1);
99 const Eigen::Vector2f projection =
v + (t * vw);
105 LaserScannerObstacleDetection::get_angle_between_vectors(
const Eigen::Vector2f& v1,
106 const Eigen::Vector2f& v2)
const
109 const Eigen::Vector2f v1_vec_normed = v1.normalized();
110 const Eigen::Vector2f v2_vec_normed = v2.normalized();
111 const float dot_product_vec =
112 v1_vec_normed(0) * v2_vec_normed(0) + v1_vec_normed(1) * v2_vec_normed(1);
113 float yaw = acos(dot_product_vec);
122 LaserScannerObstacleDetection::eval_obstacles()
127 std::unique_lock l{m_lines_buffer_mutex};
128 lines = m_lines_buffer;
129 m_lines_buffer.clear();
132 if (lines.empty() || m_only_submit_first_n_results == 0)
137 bool update_found =
false;
138 int lines_before = lines.size();
142 update_found =
false;
143 if (lines.size() < 2)
149 unsigned int remove1 = 0;
150 unsigned int remove2 = 0;
228 lines.erase(lines.begin() + remove2);
229 lines.erase(lines.begin() + remove1);
231 }
while (update_found);
233 ARMARX_DEBUG <<
"Finished updating the " << lines_before <<
" lines. Now we have "
234 << lines.size() <<
" lines. The operation took "
235 << (IceUtil::Time::now() - started).toMilliSeconds() <<
"ms";
238 std::vector<dynamicobstaclemanager::LineSegment> converted_lines;
239 for (
const auto& chain : lines)
242 if (chain.size() < 2)
247 for (
auto it = chain.begin(); it != chain.end() - 1; it++)
249 converted_lines.emplace_back(dynamicobstaclemanager::LineSegment{*it, *(it + 1)});
252 m_obstacle_manager->add_decayable_line_segments(converted_lines);
256 if (m_only_submit_first_n_results > 0)
258 m_only_submit_first_n_results--;
289 std::lock_guard l{m_enabled_mutex};
296 std::lock_guard l{m_enabled_mutex};
303 std::lock_guard l{m_enabled_mutex};
318 defs->component(m_obstacle_manager,
319 "DynamicObstacleManager",
321 "The name of the obstacle manager proxy");
322 defs->topic<LaserScannerFeaturesListener>();
324 defs->optional(m_only_submit_first_n_results,
325 "SubmitOnlyFirstNResults",
326 "Only send the first laser scanner result. -1 for all.");
327 defs->optional(m_max_distance_to_put_together,
328 "MaxDistanceOfLinesToGroup",
329 "Max distance in mm of two lines to put them together");
330 defs->optional(m_max_yaw_difference,
331 "MaxAngleDifferenceOfLinesToGroup",
332 "Max angle difference in yaw of two lines to put them together");
334 m_periodic_task_interval,
"UpdateInterval",
"The interval to check the obstacles");
336 m_accept_lines_after,
"AcceptLinesAfter",
"Accept new Lines for buffer every x ms");
337 defs->optional(m_enabled,
"ActivateOnStartup",
"Activate the component on startup.");
348 std::lock_guard l{m_enabled_mutex};
349 if (!m_enabled or globalLineSegmentChains.empty())
355 if ((IceUtil::Time::now() - m_last_accepted_lines).toMilliSeconds() > m_accept_lines_after)
357 std::unique_lock l{m_lines_buffer_mutex};
360 ARMARX_DEBUG <<
"Got " << globalLineSegmentChains.size()
361 <<
" new extracted edges to buffer.";
363 m_lines_buffer.insert(
364 m_lines_buffer.end(), globalLineSegmentChains.begin(), globalLineSegmentChains.end());
365 m_last_accepted_lines = IceUtil::Time::now();