40 constexpr
double eps = 1e-8;
53 return a(0) * b(1) - a(1) * b(0);
65 double C =
A.dot(B) -
A.dot(P) + B.dot(P) - B.dot(B);
66 double D = -
A.dot(B) -
A.dot(P) + B.dot(P) +
A.dot(
A);
74 phi = (atan(C / E) - atan(D / E)) / E;
91 double C =
A.dot(B) -
A.dot(P) + B.dot(P) - B.dot(B);
92 double D = -
A.dot(B) -
A.dot(P) + B.dot(P) +
A.dot(
A);
101 phi = (atan(C / E) - atan(D / E)) / E;
102 for (
int i = 0; i < jacobian.rows(); ++i)
104 double C_ = A_.col(i).dot(B) +
A.dot(B_.col(i)) - A_.col(i).dot(P) -
A.dot(P_.col(i)) + B_.col(i).dot(P) + B.dot(P_.col(i)) - 2 * B_.col(i).dot(B);
105 double D_ = -A_.col(i).dot(B) -
A.dot(B_.col(i)) - A_.col(i).dot(P) -
A.dot(P_.col(i)) + B_.col(i).dot(P) + B.dot(P_.col(i)) + 2 * A_.col(i).dot(
A);
107 jacobian(i) = ((C_ / E - E_ * C / E / E) / (C * C / E / E + 1) - (D_ / E - E_ * D / E / E) / (D * D / E / E + 1)) / E - E_ / E * phi;
121 double C =
cross(
A - P, B - P);
122 double D = (
A - P).
dot(B - P);
139 double C =
cross(
A - P, B - P);
140 double D = (
A - P).
dot(B - P);
142 for (
int i = 0; i < jacobian.rows(); ++i)
144 double C_ =
cross(A_.col(i) - P_.col(i), B - P) +
cross(
A - P, B_.col(i) - P_.col(i));
145 double D_ = (A_.col(i) - P_.col(i)).
dot(B - P) + (
A - P).
dot(B_.col(i) - P_.col(i));
146 jacobian(i) = (C_ * D - C * D_) / (C * C + D * D) / 2.0 /
M_PI;
152 if (phi.rows() != 1)
ThrowNamed(
"Wrong size of phi!");
156 for (std::weak_ptr<KinematicElement> welement :
scene_->GetKinematicTree().GetTree())
158 std::shared_ptr<KinematicElement> element = welement.lock();
159 if (element->is_robot_link || element->closest_robot_link.lock())
161 double mass = element->segment.getInertia().getMass();
164 KDL::Frame cog = KDL::Frame(element->segment.getInertia().getCOG());
165 KDL::Frame com_local =
scene_->GetKinematicTree().FK(element, cog,
nullptr, KDL::Frame());
166 kdl_com += com_local.p * mass;
171 if (M == 0.0)
return;
172 kdl_com = kdl_com / M;
173 Eigen::VectorXd com(2);
177 Eigen::MatrixXd supports(
kinematics[0].Phi.rows(), 2);
178 for (
int i = 0; i <
kinematics[0].Phi.rows(); ++i)
186 double n = hull.size();
190 for (std::list<int>::iterator it = hull.begin(); it != hull.end();)
193 int b = ++it == hull.end() ? *hull.begin() : *(it);
194 potential(tmp, supports.row(a).transpose(), supports.row(b).transpose(), com);
196 winding(tmp, supports.row(a).transpose(), supports.row(b).transpose(), com);
205 phi(0) = -sqrt(-
n / pot);
211 phi(0) = sqrt(-
n / pot);
218 debug_msg_.markers[0].pose.position.x = com(0);
219 debug_msg_.markers[0].pose.position.y = com(1);
222 debug_msg_.markers[1].points.resize(hull.size() + 1);
226 debug_msg_.markers[1].points[ii].x = supports(i, 0);
227 debug_msg_.markers[1].points[ii].y = supports(i, 1);
238 if (phi.rows() != 1)
ThrowNamed(
"Wrong size of phi!");
239 if (jacobian.rows() != 1 || jacobian.cols() !=
x.rows())
ThrowNamed(
"Wrong size of jacobian! " <<
x.rows());
242 Eigen::MatrixXd jacobian_com = Eigen::MatrixXd::Zero(2, jacobian.cols());
245 for (std::weak_ptr<KinematicElement> welement :
scene_->GetKinematicTree().GetTree())
247 std::shared_ptr<KinematicElement> element = welement.lock();
248 if (element->is_robot_link || element->closest_robot_link.lock())
250 double mass = element->segment.getInertia().getMass();
253 KDL::Frame cog = KDL::Frame(element->segment.getInertia().getCOG());
254 KDL::Frame com_local =
scene_->GetKinematicTree().FK(element, cog,
nullptr, KDL::Frame());
255 Eigen::MatrixXd jacobian_com_local =
scene_->GetKinematicTree().Jacobian(element, cog,
nullptr, KDL::Frame());
256 kdl_com += com_local.p * mass;
257 jacobian_com += jacobian_com_local.topRows(2) * mass;
262 if (M == 0.0)
return;
263 kdl_com = kdl_com / M;
264 Eigen::VectorXd com(2);
267 jacobian_com = jacobian_com / M;
269 Eigen::MatrixXd supports(
kinematics[0].Phi.rows(), 2);
270 Eigen::MatrixXd supportsJ(
kinematics[0].Phi.rows() * 2,
x.rows());
271 for (
int i = 0; i <
kinematics[0].Phi.rows(); ++i)
275 supportsJ.middleRows(i * 2, 2) =
kinematics[0].jacobian(i).data.topRows(2);
280 double n = hull.size();
283 Eigen::VectorXd potJ = jacobian.row(0);
285 Eigen::VectorXd tmpJ = jacobian.row(0);
286 for (std::list<int>::iterator it = hull.begin(); it != hull.end(); ++it)
289 int b = (std::next(it) == hull.end()) ? *hull.begin() : *(std::next(it));
290 potential(tmp, tmpJ, supports.row(a).transpose(), supports.row(b).transpose(), com, supportsJ.middleRows(a * 2, 2), supportsJ.middleRows(b * 2, 2), jacobian_com);
293 winding(tmp, supports.row(a).transpose(), supports.row(b).transpose(), com);
302 phi(0) = sqrt(-
n / pot);
303 jacobian.row(0) = potJ * (
n / (2 * pot * pot * phi(0)));
309 phi(0) = -sqrt(-
n / pot);
310 jacobian.row(0) = potJ * (
n / (2 * pot * pot * phi(0)));
317 debug_msg_.markers[0].pose.position.x = com(0);
318 debug_msg_.markers[0].pose.position.y = com(1);
321 debug_msg_.markers[1].points.resize(hull.size() + 1);
325 debug_msg_.markers[1].points[ii].x = supports(i, 0);
326 debug_msg_.markers[1].points[ii].y = supports(i, 1);
344 visualization_msgs::Marker mrk;
345 mrk.action = visualization_msgs::Marker::ADD;
346 mrk.header.frame_id =
"exotica/" +
scene_->GetRootFrameName();
348 mrk.type = visualization_msgs::Marker::SPHERE;
349 mrk.scale.x = mrk.scale.y = mrk.scale.z = 0.05;
357 visualization_msgs::Marker mrk;
358 mrk.action = visualization_msgs::Marker::ADD;
359 mrk.header.frame_id =
"exotica/" +
scene_->GetRootFrameName();
361 mrk.type = visualization_msgs::Marker::LINE_STRIP;
371 debug_pub_ = Server::Advertise<visualization_msgs::MarkerArray>(
ns_ +
"/exotica/QuasiStatic", 1,
true);