Go to the documentation of this file.00001
00026 #include "constrained_ik/constraints/joint_vel_limits.h"
00027 #include "constrained_ik/constrained_ik.h"
00028 #include <ros/ros.h>
00029 #include <pluginlib/class_list_macros.h>
00030 PLUGINLIB_EXPORT_CLASS(constrained_ik::constraints::JointVelLimits, constrained_ik::Constraint)
00031
00032 const double DEFAULT_WEIGHT = 1.0;
00033 const double DEFAULT_TIMESTEP = 0.1;
00035 namespace constrained_ik
00036 {
00037 namespace constraints
00038 {
00039
00040 using namespace Eigen;
00041 using namespace std;
00042
00043 JointVelLimits::JointVelLimits(): Constraint(), weight_(DEFAULT_WEIGHT), timestep_(DEFAULT_TIMESTEP)
00044 {
00045 }
00046
00047 constrained_ik::ConstraintResults JointVelLimits::evalConstraint(const SolverState &state) const
00048 {
00049 constrained_ik::ConstraintResults output;
00050 JointVelLimits::JointVelLimitsData cdata(state, this);
00051
00052 output.error = calcError(cdata);
00053 output.jacobian = calcJacobian(cdata);
00054 output.status = checkStatus(cdata);
00055
00056 return output;
00057 }
00058
00059 Eigen::VectorXd JointVelLimits::calcError(const JointVelLimits::JointVelLimitsData &cdata) const
00060 {
00061 size_t nRows = cdata.limited_joints_.size();
00062 VectorXd error(nRows);
00063 VectorXd vel_error = cdata.jvel_.cwiseAbs() - vel_limits_;
00064 for (int ii=0; ii<nRows; ++ii)
00065 {
00066 size_t jntIdx = cdata.limited_joints_[ii];
00067 int velSign = cdata.jvel_(jntIdx)<0 ? 1 : -1;
00068
00069 error(ii) = velSign * weight_ * vel_error(jntIdx) * 1.25;
00070 }
00071
00072 if (debug_ && nRows)
00073 {
00074 ROS_ERROR_STREAM("iteration " << cdata.state_.iter);
00075 ROS_ERROR_STREAM("Joint velocity: " << cdata.jvel_.transpose());
00076 ROS_ERROR_STREAM("velocity error: " << error.transpose());
00077 }
00078
00079 return error;
00080 }
00081
00082 Eigen::MatrixXd JointVelLimits::calcJacobian(const JointVelLimits::JointVelLimitsData &cdata) const
00083 {
00084 size_t nRows = cdata.limited_joints_.size();
00085 MatrixXd jacobian(nRows, numJoints());
00086
00087 for (int ii=0; ii<nRows; ++ii)
00088 {
00089 size_t jntIdx = cdata.limited_joints_[ii];
00090
00091 VectorXd tmpRow = VectorXd::Zero(numJoints());
00092 tmpRow(jntIdx) = 1.0;
00093
00094 jacobian.row(ii) = tmpRow * weight_;
00095 }
00096
00097 return jacobian;
00098 }
00099
00100 void JointVelLimits::init(const Constrained_IK *ik)
00101 {
00102 Constraint::init(ik);
00103
00104
00105 vel_limits_.resize(numJoints());
00106 for (size_t ii=0; ii<numJoints(); ++ii)
00107 vel_limits_(ii) = 2*M_PI;
00108 }
00109
00110 void JointVelLimits::loadParameters(const XmlRpc::XmlRpcValue &constraint_xml)
00111 {
00112 XmlRpc::XmlRpcValue local_xml = constraint_xml;
00113 if (!getParam(local_xml, "weights", weight_))
00114 {
00115 ROS_WARN("Avoid Joint Velocity Limits: Unable to retrieve weights member, default parameter will be used.");
00116 }
00117
00118 if (!getParam(local_xml, "timestep", timestep_))
00119 {
00120 ROS_WARN("Avoid Joint Velocity Limits: Unable to retrieve timestep member, default parameter will be used.");
00121 }
00122
00123 if (!getParam(local_xml, "debug", debug_))
00124 {
00125 ROS_WARN("Avoid Joint Velocity Limits: Unable to retrieve debug member, default parameter will be used.");
00126 }
00127 }
00128
00129
00130 template<class T>
00131 std::ostream& operator<< (std::ostream& os, const std::vector<T>& v)
00132 {
00133 if (!v.empty())
00134 {
00135 copy(v.begin(), v.end()-1, std::ostream_iterator<T>(os, ", "));
00136 os << v.back();
00137 }
00138 return os;
00139 }
00140
00141 JointVelLimits::JointVelLimitsData::JointVelLimitsData(const SolverState &state, const constraints::JointVelLimits *parent): ConstraintData(state)
00142 {
00143 if (!parent->initialized_) return;
00144 parent_ = parent;
00145
00146 jvel_ = (state_.joints - state_.joint_seed)/parent_->timestep_;
00147
00148 for (size_t ii=0; ii<parent_->numJoints(); ++ii)
00149 if ( std::abs(jvel_(ii)) > parent_->vel_limits_(ii) )
00150 limited_joints_.push_back(ii);
00151
00152
00153 if (parent_->debug_ && !limited_joints_.empty())
00154 ROS_ERROR_STREAM(limited_joints_.size() << " joint vel limits active: " << limited_joints_);
00155 }
00156
00157 }
00158 }