Go to the documentation of this file.00001
00028 #include <stomp_plugins/update_filters/constrained_cartesian_goal.h>
00029 #include <ros/console.h>
00030 #include <Eigen/Geometry>
00031 #include <eigen_conversions/eigen_msg.h>
00032 #include <moveit/robot_state/robot_state.h>
00033 #include <moveit/robot_state/conversions.h>
00034 #include <pluginlib/class_list_macros.h>
00035 #include <XmlRpcException.h>
00036
00037 PLUGINLIB_EXPORT_CLASS(stomp_moveit::update_filters::ConstrainedCartesianGoal,stomp_moveit::update_filters::StompUpdateFilter);
00038
00039 static int CARTESIAN_DOF_SIZE = 6;
00040 static int const IK_ATTEMPTS = 10;
00041 static int const IK_TIMEOUT = 0.05;
00042
00043 namespace stomp_moveit
00044 {
00045 namespace update_filters
00046 {
00047
00048 ConstrainedCartesianGoal::ConstrainedCartesianGoal():
00049 name_("ConstrainedCartesianGoal")
00050 {
00051
00052
00053 }
00054
00055 ConstrainedCartesianGoal::~ConstrainedCartesianGoal()
00056 {
00057
00058 }
00059
00060 bool ConstrainedCartesianGoal::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
00061 const std::string& group_name,const XmlRpc::XmlRpcValue& config)
00062 {
00063 group_name_ = group_name;
00064 robot_model_ = robot_model_ptr;
00065
00066 return configure(config);
00067 }
00068
00069 bool ConstrainedCartesianGoal::configure(const XmlRpc::XmlRpcValue& config)
00070 {
00071 using namespace XmlRpc;
00072
00073 try
00074 {
00075 XmlRpcValue params = config;
00076
00077 XmlRpcValue dof_nullity_param = params["constrained_dofs"];
00078 XmlRpcValue dof_thresholds_param = params["cartesian_convergence"];
00079 XmlRpcValue joint_updates_param = params["joint_update_rates"];
00080 if((dof_nullity_param.getType() != XmlRpcValue::TypeArray) ||
00081 dof_nullity_param.size() < CARTESIAN_DOF_SIZE ||
00082 dof_thresholds_param.getType() != XmlRpcValue::TypeArray ||
00083 dof_thresholds_param.size() < CARTESIAN_DOF_SIZE ||
00084 joint_updates_param.getType() != XmlRpcValue::TypeArray ||
00085 joint_updates_param.size() == 0)
00086 {
00087 ROS_ERROR("UnderconstrainedGoal received invalid array parameters");
00088 return false;
00089 }
00090
00091 for(auto i = 0u; i < dof_nullity_param.size(); i++)
00092 {
00093 kc_.constrained_dofs(i) = static_cast<int>(dof_nullity_param[i]);
00094 }
00095
00096 for(auto i = 0u; i < dof_thresholds_param.size(); i++)
00097 {
00098 kc_.cartesian_convergence_thresholds(i) = static_cast<double>(dof_thresholds_param[i]);
00099 }
00100
00101 kc_.joint_update_rates.resize(joint_updates_param.size());
00102 for(auto i = 0u; i < joint_updates_param.size(); i++)
00103 {
00104 kc_.joint_update_rates(i) = static_cast<double>(joint_updates_param[i]);
00105 }
00106
00107 kc_.max_iterations = static_cast<int>(params["max_ik_iterations"]);
00108 }
00109 catch(XmlRpc::XmlRpcException& e)
00110 {
00111 ROS_ERROR("%s failed to load parameters, %s",getName().c_str(),e.getMessage().c_str());
00112 return false;
00113 }
00114
00115 return true;
00116 }
00117
00118 bool ConstrainedCartesianGoal::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
00119 const moveit_msgs::MotionPlanRequest &req,
00120 const stomp_core::StompConfiguration &config,
00121 moveit_msgs::MoveItErrorCodes& error_code)
00122 {
00123 using namespace Eigen;
00124 using namespace moveit::core;
00125 using namespace utils::kinematics;
00126
00127 const JointModelGroup* joint_group = robot_model_->getJointModelGroup(group_name_);
00128 int num_joints = joint_group->getActiveJointModels().size();
00129 tool_link_ = joint_group->getLinkModelNames().back();
00130 state_.reset(new RobotState(robot_model_));
00131 robotStateMsgToRobotState(req.start_state,*state_);
00132
00133 const std::vector<moveit_msgs::Constraints>& goals = req.goal_constraints;
00134 if(goals.empty())
00135 {
00136 ROS_ERROR("A goal constraint was not provided");
00137 error_code.val = error_code.INVALID_GOAL_CONSTRAINTS;
00138 return false;
00139 }
00140
00141
00142 bool found_goal = false;
00143 for(const auto& g: goals)
00144 {
00145
00146 if(!g.position_constraints.empty() &&
00147 !g.orientation_constraints.empty())
00148 {
00149
00150
00151 const moveit_msgs::PositionConstraint& pos_constraint = g.position_constraints.front();
00152 const moveit_msgs::OrientationConstraint& orient_constraint = g.orientation_constraints.front();
00153
00154 KinematicConfig kc;
00155 Eigen::VectorXd joint_pose;
00156 if(createKinematicConfig(joint_group,pos_constraint,orient_constraint,req.start_state,kc))
00157 {
00158 kc_.tool_goal_pose = kc.tool_goal_pose;
00159 if(!solveIK(state_,group_name_,kc,joint_pose))
00160 {
00161 ROS_WARN("%s failed calculating ik for cartesian goal pose in the MotionPlanRequest",getName().c_str());
00162 }
00163
00164 found_goal = true;
00165 break;
00166 }
00167
00168 }
00169
00170 if(!found_goal )
00171 {
00172
00173 if(g.joint_constraints.empty())
00174 {
00175 ROS_WARN_STREAM("No joint values for the goal were found");
00176 continue;
00177 }
00178
00179 ROS_WARN("%s a cartesian goal pose in MotionPlanRequest was not provided,calculating it from FK",getName().c_str());
00180
00181
00182 const std::vector<moveit_msgs::JointConstraint>& joint_constraints = g.joint_constraints;
00183
00184
00185 for(auto& jc: joint_constraints)
00186 {
00187 state_->setVariablePosition(jc.joint_name,jc.position);
00188 }
00189
00190
00191 state_->update(true);
00192 kc_.tool_goal_pose = state_->getGlobalLinkTransform(tool_link_);
00193 found_goal = true;
00194 break;
00195
00196 }
00197 }
00198
00199 if(!found_goal)
00200 {
00201 ROS_ERROR("%s No valid goal pose was found",getName().c_str());
00202 error_code.val = error_code.INVALID_GOAL_CONSTRAINTS;
00203 return false;
00204 }
00205
00206 error_code.val = error_code.SUCCESS;
00207 return true;
00208 }
00209
00210 bool ConstrainedCartesianGoal::filter(std::size_t start_timestep,
00211 std::size_t num_timesteps,
00212 int iteration_number,
00213 const Eigen::MatrixXd& parameters,
00214 Eigen::MatrixXd& updates,
00215 bool& filtered)
00216 {
00217 using namespace Eigen;
00218 using namespace moveit::core;
00219 using namespace stomp_moveit::utils;
00220
00221
00222 filtered = false;
00223 kc_.init_joint_pose = parameters.rightCols(1);
00224 VectorXd joint_pose;
00225 MatrixXd jacb_nullspace;
00226
00227
00228 if(kinematics::computeJacobianNullSpace(state_,group_name_,tool_link_,kc_.constrained_dofs,kc_.init_joint_pose,jacb_nullspace))
00229 {
00230 kc_.init_joint_pose += jacb_nullspace*(updates.rightCols(1));
00231 }
00232 else
00233 {
00234 ROS_WARN("%s failed to project into the nullspace of the jacobian",getName().c_str());
00235 }
00236
00237 if(kinematics::solveIK(state_,group_name_,kc_,joint_pose))
00238 {
00239 filtered = true;
00240 updates.rightCols(1) = joint_pose - parameters.rightCols(1);
00241 }
00242 else
00243 {
00244 ROS_DEBUG("%s failed to update under-constrained tool goal pose due to ik error",getName().c_str());
00245 filtered = true;
00246 updates.rightCols(1) = Eigen::VectorXd::Zero(updates.rows());
00247 }
00248
00249
00250 return true;
00251 }
00252
00253 }
00254 }