Go to the documentation of this file.00001
00026 #include "constrained_ik/constrained_ik.h"
00027 #include "constrained_ik/constraints/goal_orientation.h"
00028 #include <ros/ros.h>
00029 #include <pluginlib/class_list_macros.h>
00030 PLUGINLIB_EXPORT_CLASS(constrained_ik::constraints::GoalOrientation, constrained_ik::Constraint)
00031
00032 const double DEFAULT_ORIENTATION_TOLERANCE = 0.009;
00034 namespace constrained_ik
00035 {
00036 namespace constraints
00037 {
00038
00039 using namespace Eigen;
00040
00041
00042 GoalOrientation::GoalOrientation() : Constraint(), rot_err_tol_(DEFAULT_ORIENTATION_TOLERANCE), weight_(Vector3d::Ones())
00043 {
00044 }
00045
00046 constrained_ik::ConstraintResults GoalOrientation::evalConstraint(const SolverState &state) const
00047 {
00048 constrained_ik::ConstraintResults output;
00049 GoalOrientation::GoalOrientationData cdata(state);
00050
00051 output.error = calcError(cdata);
00052 output.jacobian = calcJacobian(cdata);
00053 output.status = checkStatus(cdata);
00054
00055 return output;
00056 }
00057
00058 double GoalOrientation::calcAngle(const Eigen::Affine3d &p1, const Eigen::Affine3d &p2)
00059 {
00060 Quaterniond q1(p1.rotation()), q2(p2.rotation());
00061 return q1.angularDistance(q2);
00062 }
00063
00064 Eigen::Vector3d GoalOrientation::calcAngleError(const Eigen::Affine3d &p1, const Eigen::Affine3d &p2)
00065 {
00066 Eigen::AngleAxisd r12(p1.rotation().transpose()*p2.rotation());
00067 double theta = Constrained_IK::rangedAngle(r12.angle());
00068 return p1.rotation() * r12.axis() * theta;
00069 }
00070
00071 Eigen::VectorXd GoalOrientation::calcError(const GoalOrientation::GoalOrientationData &cdata) const
00072 {
00073 Vector3d err = calcAngleError(cdata.state_.pose_estimate, cdata.state_.goal);
00074 err = err.cwiseProduct(weight_);
00075 ROS_ASSERT(err.rows() == 3);
00076 return err;
00077 }
00078
00079
00080 Eigen::MatrixXd GoalOrientation::calcJacobian(const GoalOrientation::GoalOrientationData &cdata) const
00081 {
00082 MatrixXd tmpJ;
00083 if (!ik_->getKin().calcJacobian(cdata.state_.joints, tmpJ))
00084 throw std::runtime_error("Failed to calculate Jacobian");
00085 MatrixXd J = tmpJ.bottomRows(3);
00086
00087
00088 for (size_t ii=0; ii<3; ++ii)
00089 J.row(ii) *= weight_(ii);
00090
00091 ROS_ASSERT(J.rows() == 3);
00092 return J;
00093 }
00094
00095 bool GoalOrientation::checkStatus(const GoalOrientation::GoalOrientationData &cdata) const
00096 {
00097
00098 if (cdata.rot_err_ < rot_err_tol_)
00099 return true;
00100
00101 return false;
00102 }
00103
00104 void GoalOrientation::loadParameters(const XmlRpc::XmlRpcValue &constraint_xml)
00105 {
00106 XmlRpc::XmlRpcValue local_xml = constraint_xml;
00107 if (!getParam(local_xml, "orientation_tolerance", rot_err_tol_))
00108 {
00109 ROS_WARN("Gool Orientation: Unable to retrieve orientation_tolerance member, default parameter will be used.");
00110 }
00111
00112 Eigen::VectorXd weights;
00113 if (getParam(local_xml, "weights", weights))
00114 {
00115 if (weights.size() == 3)
00116 {
00117 weight_ = weights;
00118 }
00119 else
00120 {
00121 ROS_WARN("Gool Orientation: Unable to add weights member, value must be a array of size 3.");
00122 }
00123 }
00124 else
00125 {
00126 ROS_WARN("Gool Orientation: Unable to retrieve weights member, default parameter will be used.");
00127 }
00128
00129 if (!getParam(local_xml, "debug", debug_))
00130 {
00131 ROS_WARN("Gool Orientation: Unable to retrieve debug member, default parameter will be used.");
00132 }
00133 }
00134
00135 GoalOrientation::GoalOrientationData::GoalOrientationData(const SolverState &state): ConstraintData(state)
00136 {
00137 rot_err_ = calcAngle(state_.goal, state_.pose_estimate);
00138 }
00139
00140
00141 }
00142 }
00143