sphere_collision.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 void SphereCollision::Instantiate(const SphereCollisionInitializer& init)
38 {
39  eps_ = 1.0 / init.Precision;
40  for (std::size_t i = 0; i < init.EndEffector.size(); ++i)
41  {
42  SphereInitializer sphere(init.EndEffector[i]);
43  groups_[sphere.Group].push_back(i);
44  radiuses_.push_back(sphere.Radius);
45  visualization_msgs::Marker mrk;
46  mrk.action = visualization_msgs::Marker::ADD;
47  mrk.header.frame_id = init.ReferenceFrame;
48  mrk.id = i;
49  mrk.type = visualization_msgs::Marker::SPHERE;
50  mrk.scale.x = mrk.scale.y = mrk.scale.z = sphere.Radius * 2;
51  debug_msg_.markers.push_back(mrk);
52  }
53  for (auto& it : groups_)
54  {
55  std_msgs::ColorRGBA col = RandomColor();
56  col.a = static_cast<float>(init.Alpha);
57  for (int i : it.second)
58  {
59  debug_msg_.markers[i].color = col;
60  debug_msg_.markers[i].ns = it.first;
61  }
62  }
63 
64  if (Server::IsRos())
65  {
66  debug_pub_ = Server::Advertise<visualization_msgs::MarkerArray>(ns_ + "/CollisionSpheres", 1, true);
67  }
68 
69  dim_ = groups_.size() * (groups_.size() - 1) / 2;
70 }
71 
72 double SphereCollision::Distance(const KDL::Frame& eff_A, const KDL::Frame& eff_B, double r_A, double r_B)
73 {
74  return 1.0 / (1.0 + exp(5.0 * eps_ * ((eff_A.p - eff_B.p).Norm() - r_A - r_B)));
75 }
76 
77 void SphereCollision::Jacobian(const KDL::Frame& eff_A, const KDL::Frame& eff_B, const KDL::Jacobian& jacA, const KDL::Jacobian& jacB, double r_A, double r_B, Eigen::Block<Eigen::Ref<Eigen::MatrixXd>, 1, -1, false> ret)
78 {
79  const Eigen::Vector3d eA_minus_eB = Eigen::Map<const Eigen::Vector3d>(eff_A.p.data) - Eigen::Map<const Eigen::Vector3d>(eff_B.p.data);
80  const double eA_minus_eB_norm = eA_minus_eB.norm();
81  for (unsigned int i = 0; i < jacA.columns(); ++i)
82  {
83  ret(i) += -static_cast<double>((jacA.data.col(i).head<3>() - jacB.data.col(i).head<3>()).adjoint() * eA_minus_eB) / eA_minus_eB_norm;
84  }
85 }
86 
88 {
89  if (phi.rows() != TaskSpaceDim()) ThrowNamed("Wrong size of phi!");
90  phi.setZero();
91 
92  auto Aend = groups_.end()--;
93  auto Bend = groups_.end();
94  int phiI = 0;
95  for (auto A = groups_.begin(); A != Aend; ++A)
96  {
97  for (auto B = std::next(A); B != Bend; ++B)
98  {
99  for (std::size_t ii = 0; ii < A->second.size(); ++ii)
100  {
101  for (std::size_t jj = 0; jj < B->second.size(); ++jj)
102  {
103  int i = A->second[ii];
104  int j = B->second[jj];
105  phi(phiI) += Distance(kinematics[0].Phi(i), kinematics[0].Phi(j), radiuses_[i], radiuses_[j]);
106  }
107  }
108  ++phiI;
109  }
110  }
111 
112  if (debug_ && Server::IsRos())
113  {
114  for (std::size_t i = 0; i < debug_msg_.markers.size(); ++i)
115  {
116  debug_msg_.markers[i].pose.position.x = kinematics[0].Phi(i).p[0];
117  debug_msg_.markers[i].pose.position.y = kinematics[0].Phi(i).p[1];
118  debug_msg_.markers[i].pose.position.z = kinematics[0].Phi(i).p[2];
119  }
121  }
122 }
123 
125 {
126  if (phi.rows() != TaskSpaceDim()) ThrowNamed("Wrong size of phi!");
127  if (jacobian.rows() != TaskSpaceDim() || jacobian.cols() != kinematics[0].jacobian(0).data.cols()) ThrowNamed("Wrong size of jacobian! " << kinematics[0].jacobian(0).data.cols());
128  phi.setZero();
129  jacobian.setZero();
130 
131  auto Aend = groups_.end()--;
132  auto Bend = groups_.end();
133  int phiI = 0;
134  for (auto A = groups_.begin(); A != Aend; ++A)
135  {
136  for (auto B = std::next(A); B != Bend; ++B)
137  {
138  for (std::size_t ii = 0; ii < A->second.size(); ++ii)
139  {
140  for (std::size_t jj = 0; jj < B->second.size(); ++jj)
141  {
142  int i = A->second[ii];
143  int j = B->second[jj];
144  phi(phiI) += Distance(kinematics[0].Phi(i), kinematics[0].Phi(j), radiuses_[i], radiuses_[j]);
145  Jacobian(kinematics[0].Phi(i), kinematics[0].Phi(j), kinematics[0].jacobian(i), kinematics[0].jacobian(j), radiuses_[i], radiuses_[j], jacobian.row(phiI));
146  }
147  }
148  ++phiI;
149  }
150  }
151 
152  if (debug_ && Server::IsRos())
153  {
154  for (std::size_t i = 0; i < debug_msg_.markers.size(); ++i)
155  {
156  debug_msg_.markers[i].pose.position.x = kinematics[0].Phi(i).p[0];
157  debug_msg_.markers[i].pose.position.y = kinematics[0].Phi(i).p[1];
158  debug_msg_.markers[i].pose.position.z = kinematics[0].Phi(i).p[2];
159  }
161  }
162 }
163 
165 {
166  return dim_;
167 }
168 } // namespace exotica
void publish(const boost::shared_ptr< M > &message) const
std_msgs::ColorRGBA RandomColor()
double Distance(const KDL::Frame &eff_A, const KDL::Frame &eff_B, double r_A, double r_B)
Eigen::Ref< Eigen::VectorXd > VectorXdRef
unsigned int columns() const
std::string ns_
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Matrix< double, 6, Eigen::Dynamic > data
std::vector< double > radiuses_
#define ThrowNamed(m)
double data[3]
void Instantiate(const SphereCollisionInitializer &init) override
void Jacobian(const KDL::Frame &eff_A, const KDL::Frame &eff_B, const KDL::Jacobian &jacA, const KDL::Jacobian &jacB, double r_A, double r_B, Eigen::Block< Eigen::Ref< Eigen::MatrixXd >, 1,-1, false > ret)
void Update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi) override
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
REGISTER_TASKMAP_TYPE("SphereCollision", exotica::SphereCollision)
std::map< std::string, std::vector< int > > groups_
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
static bool IsRos()
visualization_msgs::MarkerArray debug_msg_


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