constrained_cartesian_goal.cpp
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   // TODO Auto-generated constructor stub
00052 
00053 }
00054 
00055 ConstrainedCartesianGoal::~ConstrainedCartesianGoal()
00056 {
00057   // TODO Auto-generated destructor stub
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   // storing tool goal pose
00142   bool found_goal = false;
00143   for(const auto& g: goals)
00144   {
00145 
00146     if(!g.position_constraints.empty() &&
00147         !g.orientation_constraints.empty()) // check cartesian pose constraints first
00148     {
00149 
00150       // storing cartesian goal pose using ik
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       // check joint constraints
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       // compute FK to obtain cartesian goal pose
00182       const std::vector<moveit_msgs::JointConstraint>& joint_constraints = g.joint_constraints;
00183 
00184       // copying goal values into state
00185       for(auto& jc: joint_constraints)
00186       {
00187         state_->setVariablePosition(jc.joint_name,jc.position);
00188       }
00189 
00190       // storing reference goal position tool and pose
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   // projecting update into nullspace
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 } /* namespace update_filters */
00254 } /* namespace stomp_moveit */


stomp_plugins
Author(s): Jorge Nicho
autogenerated on Sat Jun 8 2019 19:24:15