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();
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();
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);
ros::Publisher debug_pub_
void potential(double &phi, Eigen::VectorXdRefConst A, Eigen::VectorXdRefConst B, Eigen::VectorXdRefConst P)
potential Calculates electrostatic potential at pont P induced by a uniformly charged line AB...
void publish(const boost::shared_ptr< M > &message) const
Eigen::Ref< Eigen::VectorXd > VectorXdRef
visualization_msgs::MarkerArray debug_msg_
std::shared_ptr< Scene > ScenePtr
double cross(Eigen::VectorXdRefConst a, Eigen::VectorXdRefConst b)
cross 2D cross product (z coordinate of a 3D cross product of 2 vectors on a xy plane).
const Eigen::Ref< const Eigen::MatrixXd > & MatrixXdRefConst
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
void AssignScene(ScenePtr scene) override
REGISTER_TASKMAP_TYPE("QuasiStatic", exotica::QuasiStatic)
void winding(double &phi, Eigen::VectorXdRefConst A, Eigen::VectorXdRefConst B, Eigen::VectorXdRefConst P)
winding Calculates the winding number around pont P w.r.t. thw line AB.
int TaskSpaceDim() override
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
const AutoDiffScalar< Matrix< typename internal::traits< typename internal::remove_all< DerTypeA >::type >::Scalar, Dynamic, 1 > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
std::list< int > ConvexHull2D(Eigen::MatrixXdRefConst points)
QuasiStaticInitializer parameters_
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
void Update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi) override