center_of_mass.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 {
38 {
39  if (phi.rows() != dim_) ThrowNamed("Wrong size of phi!");
40  double M = mass_.sum();
41  if (M == 0.0) return;
42 
43  KDL::Vector com;
44  for (int i = 0; i < kinematics[0].Phi.rows(); ++i)
45  {
46  com += kinematics[0].Phi(i).p * mass_(i);
47  if (debug_)
48  {
49  com_links_marker_.points[i].x = kinematics[0].Phi(i).p[0];
50  com_links_marker_.points[i].y = kinematics[0].Phi(i).p[1];
51  com_links_marker_.points[i].z = kinematics[0].Phi(i).p[2];
52  }
53  }
54 
55  com = com / M;
56  for (int i = 0; i < dim_; ++i) phi(i) = com[i];
57 
58  if (debug_ && Server::IsRos())
59  {
60  com_marker_.pose.position.x = phi(0);
61  com_marker_.pose.position.y = phi(1);
62  com_marker_.pose.position.z = phi(2);
63 
64  com_marker_.header.stamp = com_links_marker_.header.stamp = ros::Time::now();
67  }
68 }
69 
71 {
72  if (phi.rows() != dim_) ThrowNamed("Wrong size of phi!");
73  if (jacobian.rows() != dim_ || jacobian.cols() != x.rows()) ThrowNamed("Wrong size of jacobian! " << x.rows());
74  jacobian.setZero();
75  KDL::Vector com;
76 
77  if (frames_.size() > 0)
78  {
79  double M = mass_.sum();
80  if (M == 0.0) return;
81  for (int i = 0; i < kinematics[0].Phi.rows(); ++i)
82  {
83  com += kinematics[0].Phi(i).p * mass_(i);
84  jacobian += mass_(i) / M * kinematics[0].jacobian(i).data.topRows(dim_);
85  if (debug_)
86  {
87  com_links_marker_.points[i].x = kinematics[0].Phi(i).p[0];
88  com_links_marker_.points[i].y = kinematics[0].Phi(i).p[1];
89  com_links_marker_.points[i].z = kinematics[0].Phi(i).p[2];
90  }
91  }
92  com = com / M;
93  }
94  else
95  {
96  if (debug_) com_links_marker_.points.resize(0);
97  double M = 0.0;
98  for (std::weak_ptr<KinematicElement> welement : scene_->GetKinematicTree().GetTree())
99  {
100  std::shared_ptr<KinematicElement> element = welement.lock();
101  if (element->is_robot_link || element->closest_robot_link.lock()) // Only for robot links and attached objects
102  {
103  double mass = element->segment.getInertia().getMass();
104  if (mass > 0)
105  {
106  KDL::Frame cog = KDL::Frame(element->segment.getInertia().getCOG());
107  KDL::Frame com_local = scene_->GetKinematicTree().FK(element, cog, nullptr, KDL::Frame());
108  Eigen::MatrixXd jacobian_com_local = scene_->GetKinematicTree().Jacobian(element, cog, nullptr, KDL::Frame());
109  com += com_local.p * mass;
110  jacobian += jacobian_com_local.topRows(dim_) * mass;
111  M += mass;
112  if (debug_)
113  {
114  geometry_msgs::Point pt;
115  pt.x = com_local.p[0];
116  pt.y = com_local.p[1];
117  pt.z = com_local.p[2];
118  com_links_marker_.points.push_back(pt);
119  }
120  }
121  }
122  }
123  if (M == 0.0) return;
124  com = com / M;
125  jacobian = jacobian / M;
126  }
127  for (int i = 0; i < dim_; ++i) phi(i) = com[i];
128 
129  if (debug_ && Server::IsRos())
130  {
131  com_marker_.pose.position.x = phi(0);
132  com_marker_.pose.position.y = phi(1);
133  com_marker_.pose.position.z = phi(2);
134 
135  com_marker_.header.stamp = com_links_marker_.header.stamp = ros::Time::now();
138  }
139 }
140 
142 {
143  return dim_;
144 }
145 
147 {
148  enable_z_ = parameters_.EnableZ;
149  if (enable_z_)
150  dim_ = 3;
151  else
152  dim_ = 2;
153 
154  if (frames_.size() > 0)
155  {
156  // NB: This may break if it's an environment frame (#230)
157  HIGHLIGHT_NAMED("CenterOfMass", "!!! WARNING !!! This may be broken and cause a segfault if you update the scene after initialisation as the weak_ptr in GetTreeMap() expire!");
158  if (debug_)
159  HIGHLIGHT_NAMED("CenterOfMass", "Initialisation with " << frames_.size() << " passed into map.");
160 
161  mass_.resize(frames_.size());
162  for (std::size_t i = 0; i < frames_.size(); ++i)
163  {
164  if (frames_[i].frame_B_link_name != "")
165  {
166  ThrowNamed("Requesting CenterOfMass frame with base other than root! '" << frames_[i].frame_A_link_name << "'");
167  }
168  frames_[i].frame_A_link_name = scene_->GetKinematicTree().GetTreeMap().at(frames_[i].frame_A_link_name).lock()->segment.getName();
169  frames_[i].frame_A_offset.p = scene_->GetKinematicTree().GetTreeMap().at(frames_[i].frame_A_link_name).lock()->segment.getInertia().getCOG();
170  mass_(i) = scene_->GetKinematicTree().GetTreeMap().at(frames_[i].frame_A_link_name).lock()->segment.getInertia().getMass();
171  }
172  if (debug_) HIGHLIGHT_NAMED("CenterOfMass", "Total model mass: " << mass_.sum() << " kg");
173  }
174 
176 }
177 
179 {
180  scene_ = scene;
181  Initialize();
182 }
183 
185 {
186  com_links_marker_.points.resize(frames_.size());
187  com_links_marker_.type = visualization_msgs::Marker::SPHERE_LIST;
188  com_links_marker_.color.a = .7f;
189  com_links_marker_.color.r = 0.5f;
190  com_links_marker_.color.g = 0.f;
191  com_links_marker_.color.b = 0.f;
192  com_links_marker_.scale.x = com_links_marker_.scale.y = com_links_marker_.scale.z = .02f;
193  com_links_marker_.action = visualization_msgs::Marker::ADD;
194 
195  com_marker_.type = visualization_msgs::Marker::CYLINDER;
196  com_marker_.color.a = 1;
197  com_marker_.color.r = 1;
198  com_marker_.color.g = 0;
199  com_marker_.color.b = 0;
200  com_marker_.scale.x = com_marker_.scale.y = .15;
201  com_marker_.scale.z = .02;
202  com_marker_.action = visualization_msgs::Marker::ADD;
203 
204  com_links_marker_.header.frame_id = com_marker_.header.frame_id =
205  "exotica/" + scene_->GetRootFrameName();
206 
207  com_links_pub_ = Server::Advertise<visualization_msgs::Marker>(object_name_ + "/com_links_marker", 1, true);
208  com_pub_ = Server::Advertise<visualization_msgs::Marker>(object_name_ + "/com_marker", 1, true);
209 }
210 } // namespace exotica
ros::Publisher com_pub_
void publish(const boost::shared_ptr< M > &message) const
std::vector< KinematicFrameRequest > frames_
Eigen::Ref< Eigen::VectorXd > VectorXdRef
ros::Publisher com_links_pub_
void Update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi) override
std::shared_ptr< Scene > ScenePtr
Eigen::VectorXd mass_
void AssignScene(ScenePtr scene) override
std::string object_name_
visualization_msgs::Marker com_marker_
#define ThrowNamed(m)
visualization_msgs::Marker com_links_marker_
double x() const
REGISTER_TASKMAP_TYPE("CenterOfMass", exotica::CenterOfMass)
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
int TaskSpaceDim() override
#define HIGHLIGHT_NAMED(name, x)
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
static Time now()
static bool IsRos()


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