70 #include <sensor_msgs/Range.h> 71 #include <visualization_msgs/Marker.h> 82 nh.
advertise<visualization_msgs::Marker>(
"/obstacle_viz", 10));
103 float r,
float g,
float b,
int id)
105 visualization_msgs::Marker line;
106 line.type = visualization_msgs::Marker::LINE_LIST;
107 line.action = visualization_msgs::Marker::MODIFY;
114 line.scale.x = line.scale.y = line.scale.z = 0.01;
115 line.pose.position.x = 0;
116 line.pose.position.y = 0;
117 line.pose.orientation.w = 1;
118 geometry_msgs::Point gp1, gp2;
125 line.points.push_back(gp1);
126 line.points.push_back(gp2);
132 visualization_msgs::Marker line;
133 line.type = visualization_msgs::Marker::LINE_LIST;
134 line.action = visualization_msgs::Marker::DELETE;
154 float &min_dist_left,
155 float &min_dist_right,
164 for (
const auto& points : lines) {
165 float x0 = points.first.x();
166 float y0 = points.first.y();
167 float x1 = points.second.x();
168 float y1 = points.second.y();
172 float ylen = y1 - y0;
175 check_dist(a0 * x0 + (1.0 - a0) * x1, forward, min_dist);
176 check_dist(a1 * x1 + (1.0 - a1) * x0, forward, min_dist);
180 float ylen = y0 - y1;
183 check_dist(a0 * x0 + (1.0 - a0) * x1, forward, min_dist);
184 check_dist(a1 * x1 + (1.0 - a1) * x0, forward, min_dist);
197 float xlen = x1 - x0;
199 float af = (x1 - robot_front_length - x0) / xlen;
200 float yb = ab * y0 + (1.0 - ab) * y1;
201 float yf = af * y1 + (1.0 - af) * y0;
202 if (yb > 0 && yb < min_dist_left) {
205 if (yb < 0 && -yb < min_dist_right) {
206 min_dist_right = -yb;
208 if (yf> 0 && yf < min_dist_left) {
211 if (yf < 0 && -yf < min_dist_right) {
212 min_dist_right = -yf;
215 else if (x1 < -robot_back_length && x0 > robot_front_length) {
217 float xlen = x0 - x1;
219 float af = (x0 - robot_front_length - x1) / xlen;
220 float yb = ab * y1 + (1.0 - ab) * y0;
221 float yf = af * y0 + (1.0 - af) * y1;
222 if (yb > 0 && yb < min_dist_left) {
225 if (yb < 0 && -yb < min_dist_right) {
226 min_dist_right = -yb;
228 if (yf> 0 && yf < min_dist_left) {
231 if (yf < 0 && -yf < min_dist_right) {
232 min_dist_right = -yf;
237 if (y0 > 0 && y0 < min_dist_left) {
240 if (y0 < 0 && -y0 < min_dist_right) {
241 min_dist_right = -y0;
245 if (y1> 0 && y1 < min_dist_left) {
248 if (y1 < 0 && -y1 < min_dist_right) {
249 min_dist_right = -y1;
257 fl.setY(min_dist_left);
259 fr.setY(min_dist_right);
262 for (
const auto& p : pts) {
271 if (y > 0 && y < min_dist_left) {
274 else if (y < 0 && -y < min_dist_right) {
294 tf2::Vector3(fl.x(), fl.y(), 0), 0, 0, 1, 30000);
297 tf2::Vector3(fr.x(), -fr.y(), 0), 0, 0, 1, 30001);
309 tf2::Vector3(min_dist,
robot_width, 0), 1, 0, 0, 10000);
312 tf2::Vector3(min_dist, -
robot_width, 0), 0.5, 0, 0, 10020);
315 tf2::Vector3(min_dist,
robot_width, 0), 0.5, 0, 0, 10030);
320 tf2::Vector3(-min_dist,
robot_width, 0), 1, 0, 0, 10000);
331 return radians * 180.0 / M_PI;
340 bool left,
float& min_dist)
const 342 float theta_int = theta - std::atan2(y, x);
343 if (theta_int < -M_PI) {
344 theta_int += 2.0 * M_PI;
346 if (theta_int > M_PI) {
347 theta_int -= 2.0 * M_PI;
349 if (left && theta_int > 0 && theta_int < min_dist) {
350 min_dist = theta_int;
352 if (!left && theta_int < 0 && -theta_int < min_dist) {
353 min_dist = -theta_int;
359 float min_angle = M_PI;
365 0.28, 0.5, 1, 10003);
368 0.28, 0.5, 1, 10004);
371 0.28, 0.5, 1, 10005);
374 0.28, 0.5, 1, 10006);
376 for (
const auto& p : points) {
380 float theta = std::atan2(y, x);
381 float r_squared = x*x + y*y;
428 rotation = min_angle;
431 rotation = -min_angle;
433 float sin_theta = std::sin(rotation);
434 float cos_theta = std::cos(rotation);
437 if (std::abs(min_angle) < M_PI) {
446 draw_line(tf2::Vector3(x_fl, y_fl, 0), tf2::Vector3(x_bl, y_bl, 0),
448 draw_line(tf2::Vector3(x_bl, y_bl, 0), tf2::Vector3(x_br, y_br, 0),
450 draw_line(tf2::Vector3(x_br, y_br, 0), tf2::Vector3(x_fr, y_fr, 0),
452 draw_line(tf2::Vector3(x_fr, y_fr, 0), tf2::Vector3(x_fl, y_fl, 0),
468 const float radius = (float) std::abs(linear/angular);
469 const bool forward = linear >= 0;
470 const bool left = angular >= 0;
473 const auto point_of_rotation = tf2::Vector3(0, (left) ? radius : -radius, 0);
479 (left) ? robot_width: -robot_width, 0) - point_of_rotation;
483 const float outer_radius_sq = outer_point.length2();
484 const float outer_theta = std::atan2(outer_point.y(), outer_point.x());
485 const float inner_radius_sq = inner_point.length2();
489 const auto angle_relevant = [&outer_theta, &left, &forward](
float angle) ->
bool {
492 return angle > outer_theta;
494 return angle < outer_theta;
502 return angle < outer_theta;
504 return angle > outer_theta;
509 float closest_angle = M_PI;
511 for (
const auto& p : points) {
514 const tf2::Vector3 p_in_rot = p - point_of_rotation;
516 const float p_radius_sq = p_in_rot.length2();
518 if(p_radius_sq < outer_radius_sq && p_radius_sq > inner_radius_sq) {
520 const float p_theta = std::atan2(p_in_rot.y(), p_in_rot.x());
521 if (angle_relevant(p_theta) && p_theta < M_PI) {
526 closest_angle = std::min(closest_angle, p_theta);
533 return closest_angle;
float robot_back_length_sq
void check_dist(float x, bool forward, float &min_dist) const
void publish(const boost::shared_ptr< M > &message) const
void check_angle(float theta, float x, float y, bool left, float &min_dist) const
float robot_front_length_sq
float obstacle_arc_angle(double linear, double angular)
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
ObstaclePoints & ob_points
float degrees(float radians) const
float obstacle_angle(bool left)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
float obstacle_dist(bool forward, float &left_dist, float &right_dist, tf2::Vector3 &fl, tf2::Vector3 &fr)
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void draw_line(const tf2::Vector3 &p1, const tf2::Vector3 &p2, float r, float g, float b, int id)
std::vector< Line > get_lines(ros::Duration max_age)
std::vector< tf2::Vector3 > get_points(ros::Duration max_age)
CollisionChecker(ros::NodeHandle &nh, tf2_ros::Buffer &tf_buffer, ObstaclePoints &op)