eff_axis_alignment.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018, Wolfgang Merkt
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 
31 
32 #include <exotica_core/server.h>
34 
36 
37 namespace exotica
38 {
40 {
41  N = scene_->GetKinematicTree().GetNumControlledJoints();
42 
43  n_frames_ = parameters_.EndEffector.size();
44  if (debug_) HIGHLIGHT_NAMED("EffAxisAlignment", "Number of EndEffectors: " << n_frames_);
45  axis_.resize(3, n_frames_);
46  dir_.resize(3, n_frames_);
47 
48  frames_.resize(2 * n_frames_);
49  for (int i = 0; i < n_frames_; ++i)
50  {
51  FrameWithAxisAndDirectionInitializer frame(parameters_.EndEffector[i]);
52  axis_.col(i) = frame.Axis.normalized();
53  dir_.col(i) = frame.Direction.normalized();
54 
55  frames_[i + n_frames_] = frames_[i];
56  tf::vectorEigenToKDL(axis_.col(i), frames_[i + n_frames_].frame_A_offset.p);
57  }
58 
59  if (debug_)
60  {
61  for (int i = 0; i < n_frames_; ++i)
62  {
63  HIGHLIGHT_NAMED("EffAxisAlignment",
64  "Frame " << frames_[i].frame_A_link_name << ":"
65  << "\tAxis=" << axis_.col(i).transpose()
66  << "\tDirection=" << dir_.col(i).transpose());
67  }
68  }
69 
70  if (Server::IsRos())
71  {
72  pub_debug_ = Server::Advertise<visualization_msgs::MarkerArray>(object_name_ + "/debug", 1, true);
73  msg_debug_.markers.reserve(n_frames_ * 2);
74  for (int i = 0; i < n_frames_; ++i)
75  {
76  visualization_msgs::Marker marker;
77  marker.action = visualization_msgs::Marker::ADD;
78  marker.type = visualization_msgs::Marker::ARROW;
79  marker.frame_locked = true;
80  marker.header.frame_id = "exotica/" + scene_->GetKinematicTree().GetRootFrameName();
81  marker.scale.x = 0.025; // Shaft diameter
82  marker.scale.y = 0.05; // Head diameter
83  marker.scale.z = 0.05; // Head length
84  marker.ns = frames_[i].frame_A_link_name;
85  marker.pose.orientation.w = 1.0;
86  marker.points.resize(2);
87 
88  // Current: red
89  {
90  marker.color = GetColor(1., 0., 0., 0.5);
91  marker.id = i;
92  msg_debug_.markers.emplace_back(marker);
93  }
94 
95  // Target: green
96  {
97  marker.color = GetColor(0., 1., 0., 0.5);
98  marker.id = i + n_frames_;
99  msg_debug_.markers.emplace_back(marker);
100  }
101  }
102 
103  // Clear pre-existing markers
104  visualization_msgs::MarkerArray msg;
105  msg.markers.resize(1);
106  msg.markers[0].action = 3; // DELETE_ALL
107  pub_debug_.publish(msg);
108  }
109 }
110 
112 {
113  scene_ = scene;
114  Initialize();
115 }
116 
118 {
119  if (phi.rows() != n_frames_) ThrowNamed("Wrong size of phi!");
120 
121  for (int i = 0; i < n_frames_; ++i)
122  {
123  link_position_in_base_ = Eigen::Map<Eigen::Vector3d>(kinematics[0].Phi(i).p.data);
124  link_axis_position_in_base_ = Eigen::Map<Eigen::Vector3d>(kinematics[0].Phi(i + n_frames_).p.data);
125 
126  Eigen::Vector3d axisInBase = link_axis_position_in_base_ - link_position_in_base_;
127  phi(i) = axisInBase.dot(dir_.col(i)) - 1.0;
128  }
129 }
130 
132 {
133  if (phi.rows() != n_frames_) ThrowNamed("Wrong size of phi!");
134  if (jacobian.rows() != n_frames_ || jacobian.cols() != kinematics[0].jacobian(0).data.cols()) ThrowNamed("Wrong size of jacobian! " << kinematics[0].jacobian(0).data.cols());
135 
136  for (int i = 0; i < n_frames_; ++i)
137  {
138  link_position_in_base_ = Eigen::Map<Eigen::Vector3d>(kinematics[0].Phi(i).p.data);
139  link_axis_position_in_base_ = Eigen::Map<Eigen::Vector3d>(kinematics[0].Phi(i + n_frames_).p.data);
140 
141  const Eigen::Vector3d axisInBase = link_axis_position_in_base_ - link_position_in_base_;
142  const Eigen::MatrixXd axisInBaseJacobian = kinematics[0].jacobian[i + n_frames_].data.topRows<3>() - kinematics[0].jacobian[i].data.topRows<3>();
143 
144  phi(i) = axisInBase.dot(dir_.col(i)) - 1.0;
145  jacobian.row(i) = dir_.col(i).transpose() * axisInBaseJacobian;
146 
147  if (Server::IsRos() && debug_)
148  {
149  constexpr double arrow_length = 0.25;
150  // Current - red
151  msg_debug_.markers[i].points[0].x = link_position_in_base_.x();
152  msg_debug_.markers[i].points[0].y = link_position_in_base_.y();
153  msg_debug_.markers[i].points[0].z = link_position_in_base_.z();
154  msg_debug_.markers[i].points[1].x = link_position_in_base_.x() + arrow_length * axisInBase.x();
155  msg_debug_.markers[i].points[1].y = link_position_in_base_.y() + arrow_length * axisInBase.y();
156  msg_debug_.markers[i].points[1].z = link_position_in_base_.z() + arrow_length * axisInBase.z();
157 
158  // Target - green
159  msg_debug_.markers[i + n_frames_].points[0].x = link_position_in_base_.x();
160  msg_debug_.markers[i + n_frames_].points[0].y = link_position_in_base_.y();
161  msg_debug_.markers[i + n_frames_].points[0].z = link_position_in_base_.z();
162  msg_debug_.markers[i + n_frames_].points[1].x = link_position_in_base_.x() + arrow_length * dir_.col(i).x();
163  msg_debug_.markers[i + n_frames_].points[1].y = link_position_in_base_.y() + arrow_length * dir_.col(i).y();
164  msg_debug_.markers[i + n_frames_].points[1].z = link_position_in_base_.z() + arrow_length * dir_.col(i).z();
165 
167  }
168  }
169 }
170 
172 {
173  return n_frames_;
174 }
175 
176 Eigen::Vector3d EffAxisAlignment::GetDirection(const std::string& frame_name) const
177 {
178  for (int i = 0; i < n_frames_; ++i)
179  {
180  if (frames_[i].frame_A_link_name == frame_name)
181  {
182  return dir_.col(i);
183  }
184  }
185  ThrowPretty("Direction for frame with name " << frame_name << " could not be found.");
186 }
187 
188 void EffAxisAlignment::SetDirection(const std::string& frame_name, const Eigen::Vector3d& dir_in)
189 {
190  for (int i = 0; i < n_frames_; ++i)
191  {
192  if (frames_[i].frame_A_link_name == frame_name)
193  {
194  dir_.col(i) = dir_in.normalized();
195  return;
196  }
197  }
198  ThrowPretty("Could not find frame with name " << frame_name << ".");
199 }
200 
201 Eigen::Vector3d EffAxisAlignment::GetAxis(const std::string& frame_name) const
202 {
203  for (int i = 0; i < n_frames_; ++i)
204  {
205  if (frames_[i].frame_A_link_name == frame_name)
206  {
207  return axis_.col(i);
208  }
209  }
210  ThrowPretty("Axis for frame with name " << frame_name << " could not be found.");
211 }
212 
213 void EffAxisAlignment::SetAxis(const std::string& frame_name, const Eigen::Vector3d& axis_in)
214 {
215  for (int i = 0; i < n_frames_; ++i)
216  {
217  if (frames_[i].frame_A_link_name == frame_name)
218  {
219  axis_.col(i) = axis_in.normalized();
220  tf::vectorEigenToKDL(axis_.col(i), frames_[i + n_frames_].frame_A_offset.p);
221  return;
222  }
223  }
224  ThrowPretty("Could not find frame with name " << frame_name << ".");
225 }
226 } // namespace exotica
void SetDirection(const std::string &frame_name, const Eigen::Vector3d &dir_in)
void publish(const boost::shared_ptr< M > &message) const
std::vector< KinematicFrameRequest > frames_
Eigen::Ref< Eigen::VectorXd > VectorXdRef
Eigen::Vector3d link_axis_position_in_base_
#define ThrowPretty(m)
Eigen::Vector3d GetAxis(const std::string &frame_name) const
std_msgs::ColorRGBA GetColor(double r, double g, double b, double a=1.0)
Eigen::Vector3d GetDirection(const std::string &frame_name) const
std::shared_ptr< Scene > ScenePtr
std::string object_name_
#define ThrowNamed(m)
void SetAxis(const std::string &frame_name, const Eigen::Vector3d &axis_in)
REGISTER_TASKMAP_TYPE("EffAxisAlignment", exotica::EffAxisAlignment)
void Update(Eigen::VectorXdRefConst q, Eigen::VectorXdRef phi) override
void vectorEigenToKDL(const Eigen::Matrix< double, 3, 1 > &e, KDL::Vector &k)
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
visualization_msgs::MarkerArray msg_debug_
Eigen::Vector3d link_position_in_base_
#define HIGHLIGHT_NAMED(name, x)
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void AssignScene(ScenePtr scene) override
static bool IsRos()


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