point_to_line.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018, University of Edinburgh
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without specific
15 // prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 
30 #include <exotica_core/server.h>
32 
34 
35 namespace exotica
36 {
37 PointToLine::PointToLine() = default;
38 PointToLine::~PointToLine() = default;
39 
40 Eigen::Vector3d PointToLine::Direction(const Eigen::Vector3d &point)
41 {
42  // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
43  // let:
44  // s: start of line
45  // e: end of line
46  // p: point
47  // then the point on vector v = e-s that is closest to p is vp = s + t*(e-s) with
48  // t = -((s-p)*(e-s)) / (|e-s|^2) (* denotes the dot product)
49  if (debug_) HIGHLIGHT_NAMED("P2L", "\e[4m" << link_name_ << "\e[0m");
50  if (debug_) HIGHLIGHT_NAMED("P2L", "p " << point.transpose());
51  if (debug_) HIGHLIGHT_NAMED("P2L", "ls " << line_start_.transpose());
52  if (debug_) HIGHLIGHT_NAMED("P2L", "le " << line_end_.transpose());
53  double t = -(line_start_ - point).dot(line_) / line_.squaredNorm();
54  std::stringstream ss;
55  ss << "t " << t;
56  if (!infinite_)
57  {
58  // clip to to range [0,1]
59  t = std::min(std::max(0.0, t), 1.0);
60  ss << ", clipped |t| " << t;
61  }
62  if (debug_) HIGHLIGHT_NAMED("P2L", ss.str());
63 
64  // vector from point 'p' to point 'vp' on line
65  // vp = line_start_ + t * (line_end_-line_start_)
66  const Eigen::Vector3d dv = line_start_ + (t * line_) - point;
67  if (debug_) HIGHLIGHT_NAMED("P2L", "vp " << (line_start_ + (t * line_)).transpose());
68  if (debug_) HIGHLIGHT_NAMED("P2L", "dv " << dv.transpose());
69  return dv;
70 }
71 
72 Eigen::Vector3d PointToLine::GetEndPoint()
73 {
74  return line_end_;
75 }
76 
77 void PointToLine::SetEndPoint(const Eigen::Vector3d &point)
78 {
79  line_end_ = point;
81 }
82 
84 {
85  if (phi.rows() != kinematics[0].Phi.rows() * 3) ThrowNamed("Wrong size of phi!");
86 
87  for (int i = 0; i < kinematics[0].Phi.rows(); ++i)
88  {
89  const Eigen::Vector3d p = line_start_ + Eigen::Map<const Eigen::Vector3d>(kinematics[0].Phi(i).p.data);
90  phi.segment<3>(i * 3) = -Direction(p);
91  }
92 }
93 
95 {
96  if (phi.rows() != kinematics[0].Phi.rows() * 3) ThrowNamed("Wrong size of phi!");
97  if (jacobian.rows() != kinematics[0].jacobian.rows() * 3 || jacobian.cols() != kinematics[0].jacobian(0).data.cols()) ThrowNamed("Wrong size of jacobian! " << kinematics[0].jacobian(0).data.cols());
98 
99  for (int i = 0; i < kinematics[0].Phi.rows(); ++i)
100  {
101  // point in base frame
102  const Eigen::Vector3d p = line_start_ + Eigen::Map<const Eigen::Vector3d>(kinematics[0].Phi(i).p.data);
103  // direction from point to line
104  const Eigen::Vector3d dv = Direction(p);
105  phi.segment<3>(i * 3) = dv;
106 
107  if ((dv + p - line_start_).norm() < std::numeric_limits<double>::epsilon())
108  {
109  // clipped (t=0) case
110  jacobian.middleRows<3>(i * 3) = -kinematics[0].jacobian[i].data.topRows<3>();
111  }
112  else
113  {
114  for (int j = 0; j < jacobian.cols(); ++j)
115  {
116  jacobian.middleRows<3>(i * 3).col(j) = kinematics[0].jacobian[i].data.topRows<3>().col(j).dot(line_ / line_.squaredNorm()) * line_ - kinematics[0].jacobian[i].data.topRows<3>().col(j);
117  }
118  }
119 
120  // visualisation of point, line and their distance
121  if (visualize_ && Server::IsRos())
122  {
123  const ros::Time t = ros::Time::now();
124  const std::string common_frame = "exotica/" + base_name_;
125  visualization_msgs::MarkerArray ma;
126  {
127  // line in base frame
128  visualization_msgs::Marker mc;
129  mc.header.stamp = t;
130  mc.frame_locked = true;
131  mc.header.frame_id = common_frame;
132  mc.ns = "cam/line/" + object_name_;
133  mc.type = visualization_msgs::Marker::ARROW;
134  mc.scale.x = 0.01;
135  mc.scale.y = 0.01;
136  mc.scale.z = 0.01;
137  // line start
138  geometry_msgs::Point pp;
139  pp.x = line_start_.x();
140  pp.y = line_start_.y();
141  pp.z = line_start_.z();
142  mc.points.push_back(pp);
143  // line end
144  const Eigen::Vector3d pe = p + dv;
145  pp.x = pe.x();
146  pp.y = pe.y();
147  pp.z = pe.z();
148  mc.points.push_back(pp);
149  mc.color.r = 1;
150  mc.color.g = 1;
151  mc.color.b = 0;
152  mc.color.a = 1;
153  ma.markers.push_back(mc);
154  }
155  {
156  // point in link frame
157  visualization_msgs::Marker ml;
158  ml.header.stamp = t;
159  ml.frame_locked = true;
160  ml.header.frame_id = common_frame;
161  ml.ns = "lnk/point/" + object_name_;
162  ml.type = visualization_msgs::Marker::SPHERE;
163  ml.scale.x = 0.03;
164  ml.scale.y = 0.03;
165  ml.scale.z = 0.03;
166  ml.color.r = 1;
167  ml.color.g = 0;
168  ml.color.b = 0;
169  ml.color.a = 1;
170  ml.pose.position.x = p.x();
171  ml.pose.position.y = p.y();
172  ml.pose.position.z = p.z();
173  ma.markers.push_back(ml);
174  }
175  {
176  // draw 'dv' starting at 'p' in base frame
177  visualization_msgs::Marker mdv;
178  mdv.header.stamp = t;
179  mdv.frame_locked = true;
180  mdv.header.frame_id = common_frame;
181  mdv.ns = "dv/" + object_name_;
182  mdv.type = visualization_msgs::Marker::ARROW;
183  mdv.scale.x = 0.001;
184  mdv.scale.y = 0.01;
185  mdv.scale.z = 0.01;
186  mdv.pose.position.x = p.x();
187  mdv.pose.position.y = p.y();
188  mdv.pose.position.z = p.z();
189  mdv.points.push_back(geometry_msgs::Point());
190  geometry_msgs::Point pdv;
191  pdv.x = dv.x();
192  pdv.y = dv.y();
193  pdv.z = dv.z();
194  mdv.points.push_back(pdv);
195  mdv.color.r = 0;
196  mdv.color.g = 1;
197  mdv.color.b = 0;
198  mdv.color.a = 0.5;
199  ma.markers.push_back(mdv);
200  }
201  pub_marker_.publish(ma);
202  {
203  ma.markers.clear();
204  visualization_msgs::Marker mt;
205  mt.header.stamp = t;
206  mt.frame_locked = true;
207  mt.header.frame_id = common_frame;
208  mt.ns = "lnk/label/" + object_name_;
209  mt.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
210  mt.text = link_name_;
211  mt.pose.position.x = p.x();
212  mt.pose.position.y = p.y();
213  mt.pose.position.z = p.z();
214  mt.scale.x = 0.05;
215  mt.scale.y = 0.05;
216  mt.scale.z = 0.05;
217  mt.color.r = 1;
218  mt.color.g = 1;
219  mt.color.b = 1;
220  mt.color.a = 1;
221  ma.markers.push_back(mt);
223  }
224  }
225  }
226 }
227 
228 void PointToLine::Instantiate(const PointToLineInitializer &init)
229 {
230  link_name_ = frames_[0].frame_A_link_name;
231  base_name_ = frames_[0].frame_B_link_name;
232 
233  line_start_ = Eigen::Map<Eigen::Vector3d>(frames_[0].frame_B_offset.p.data);
234  line_end_ = init.EndPoint;
235 
236  line_ = line_end_ - line_start_;
237  infinite_ = init.Infinite;
238 
239  visualize_ = init.Visualise;
240 
241  if (visualize_ && Server::IsRos())
242  {
243  pub_marker_ = Server::Advertise<visualization_msgs::MarkerArray>("p2l", 1, true);
244  pub_marker_label_ = Server::Advertise<visualization_msgs::MarkerArray>("p2l_label", 1, true);
245  // delete previous markers
246  visualization_msgs::Marker md;
247  md.action = 3; // DELETEALL
248  visualization_msgs::MarkerArray ma;
249  ma.markers.push_back(md);
250  pub_marker_.publish(ma);
251  pub_marker_label_.publish(ma);
252  }
253 }
254 
256 {
257  return kinematics[0].Phi.rows() * 3;
258 }
259 } // namespace exotica
Eigen::Vector3d line_
vector from start to end point of line
Definition: point_to_line.h:63
Eigen::Vector3d line_end_
end point of line in base frame
Definition: point_to_line.h:62
void publish(const boost::shared_ptr< M > &message) const
std::vector< KinematicFrameRequest > frames_
std::string link_name_
frame of defined point
Definition: point_to_line.h:67
Eigen::Vector3d Direction(const Eigen::Vector3d &point)
direction computes the vector from a point to its projection on a line
Eigen::Vector3d line_start_
start point of line in base frame
Definition: point_to_line.h:61
Eigen::Ref< Eigen::VectorXd > VectorXdRef
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PointToLine()
int TaskSpaceDim() override
std::string base_name_
frame of defined line
Definition: point_to_line.h:68
void Update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi) override
ros::Publisher pub_marker_label_
marker label
Definition: point_to_line.h:71
std::string object_name_
#define ThrowNamed(m)
ros::Publisher pub_marker_
publish marker for RViz
Definition: point_to_line.h:70
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
void Instantiate(const PointToLineInitializer &init) override
#define HIGHLIGHT_NAMED(name, x)
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
Eigen::Vector3d GetEndPoint()
REGISTER_TASKMAP_TYPE("PointToLine", exotica::PointToLine)
static Time now()
void SetEndPoint(const Eigen::Vector3d &point)
static bool IsRos()


exotica_core_task_maps
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Sat Apr 10 2021 02:36:09