Go to the documentation of this file.00001
00026 #include <stomp_plugins/cost_functions/tool_goal_pose.h>
00027 #include <XmlRpcException.h>
00028 #include <pluginlib/class_list_macros.h>
00029 #include <stomp_moveit/utils/kinematics.h>
00030 #include <ros/console.h>
00031
00032 PLUGINLIB_EXPORT_CLASS(stomp_moveit::cost_functions::ToolGoalPose,stomp_moveit::cost_functions::StompCostFunction);
00033
00034 static const int CARTESIAN_DOF_SIZE = 6;
00035
00036 namespace stomp_moveit
00037 {
00038 namespace cost_functions
00039 {
00040
00041 ToolGoalPose::ToolGoalPose():
00042 name_("ToolGoalPose")
00043 {
00044
00045
00046 }
00047
00048 ToolGoalPose::~ToolGoalPose()
00049 {
00050
00051 }
00052
00053 bool ToolGoalPose::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
00054 const std::string& group_name,XmlRpc::XmlRpcValue& config)
00055 {
00056 group_name_ = group_name;
00057 robot_model_ = robot_model_ptr;
00058
00059 return configure(config);
00060 }
00061
00062 bool ToolGoalPose::configure(const XmlRpc::XmlRpcValue& config)
00063 {
00064 using namespace XmlRpc;
00065
00066 try
00067 {
00068 XmlRpcValue params = config;
00069
00070 XmlRpcValue dof_nullity_param = params["constrained_dofs"];
00071 XmlRpcValue pos_error_range_param = params["position_error_range"];
00072 XmlRpcValue orient_error_range_param = params["orientation_error_range"];
00073
00074 if((dof_nullity_param.getType() != XmlRpcValue::TypeArray) || dof_nullity_param.size() < CARTESIAN_DOF_SIZE ||
00075 (pos_error_range_param.getType() != XmlRpcValue::TypeArray) || pos_error_range_param.size() != 2 ||
00076 (orient_error_range_param.getType() != XmlRpcValue::TypeArray) || orient_error_range_param.size() != 2 )
00077 {
00078 ROS_ERROR("%s received invalid array parameters",getName().c_str());
00079 return false;
00080 }
00081
00082 dof_nullity_.resize(CARTESIAN_DOF_SIZE);
00083 for(auto i = 0u; i < dof_nullity_param.size(); i++)
00084 {
00085 dof_nullity_(i) = static_cast<int>(dof_nullity_param[i]);
00086 }
00087
00088 position_error_range_.first = static_cast<double>(pos_error_range_param[0]);
00089 position_error_range_.second = static_cast<double>(pos_error_range_param[1]);
00090
00091 orientation_error_range_.first = static_cast<double>(orient_error_range_param[0]);
00092 orientation_error_range_.second = static_cast<double>(orient_error_range_param[1]);
00093
00094 position_cost_weight_ = static_cast<double>(params["position_cost_weight"]);
00095
00096 orientation_cost_weight_ = static_cast<double>(params["orientation_cost_weight"]);
00097
00098
00099 cost_weight_ = position_cost_weight_ + orientation_cost_weight_;
00100
00101 }
00102 catch(XmlRpc::XmlRpcException& e)
00103 {
00104 ROS_ERROR("%s failed to load parameters, %s",getName().c_str(),e.getMessage().c_str());
00105 return false;
00106 }
00107
00108 return true;
00109 }
00110
00111 bool ToolGoalPose::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
00112 const moveit_msgs::MotionPlanRequest &req,
00113 const stomp_core::StompConfiguration &config,
00114 moveit_msgs::MoveItErrorCodes& error_code)
00115 {
00116 using namespace Eigen;
00117 using namespace moveit::core;
00118
00119 const JointModelGroup* joint_group = robot_model_->getJointModelGroup(group_name_);
00120 int num_joints = joint_group->getActiveJointModels().size();
00121 tool_link_ = joint_group->getLinkModelNames().back();
00122 state_.reset(new RobotState(robot_model_));
00123 robotStateMsgToRobotState(req.start_state,*state_);
00124
00125 const std::vector<moveit_msgs::Constraints>& goals = req.goal_constraints;
00126 if(goals.empty())
00127 {
00128 ROS_ERROR("A goal constraint was not provided");
00129 error_code.val = error_code.INVALID_GOAL_CONSTRAINTS;
00130 return false;
00131 }
00132
00133
00134 bool found_goal = false;
00135 for(const auto& g: goals)
00136 {
00137 if(!g.position_constraints.empty() &&
00138 !g.orientation_constraints.empty())
00139 {
00140
00141 const moveit_msgs::PositionConstraint& pos_constraint = g.position_constraints.front();
00142 const moveit_msgs::OrientationConstraint& orient_constraint = g.orientation_constraints.front();
00143
00144 geometry_msgs::Pose pose;
00145 pose.position = pos_constraint.constraint_region.primitive_poses[0].position;
00146 pose.orientation = orient_constraint.orientation;
00147 tf::poseMsgToEigen(pose,tool_goal_pose_);
00148 found_goal = true;
00149 break;
00150
00151 }
00152
00153
00154 if(!found_goal)
00155 {
00156 ROS_WARN("%s a cartesian goal pose in MotionPlanRequest was not provided,calculating it from FK",getName().c_str());
00157
00158
00159 if(g.joint_constraints.empty())
00160 {
00161 ROS_ERROR_STREAM("No joint values for the goal were found");
00162 error_code.val = error_code.INVALID_GOAL_CONSTRAINTS;
00163 return false;
00164 }
00165
00166
00167 const std::vector<moveit_msgs::JointConstraint>& joint_constraints = g.joint_constraints;
00168
00169
00170 for(auto& jc: joint_constraints)
00171 {
00172 state_->setVariablePosition(jc.joint_name,jc.position);
00173 }
00174
00175
00176 state_->update(true);
00177 tool_goal_pose_ = state_->getGlobalLinkTransform(tool_link_);
00178 found_goal = true;
00179 break;
00180 }
00181 }
00182
00183
00184
00185 return true;
00186 }
00187
00188 bool ToolGoalPose::computeCosts(const Eigen::MatrixXd& parameters,
00189 std::size_t start_timestep,
00190 std::size_t num_timesteps,
00191 int iteration_number,
00192 int rollout_number,
00193 Eigen::VectorXd& costs,
00194 bool& validity)
00195 {
00196
00197 using namespace Eigen;
00198 using namespace utils::kinematics;
00199 validity = true;
00200
00201 auto compute_scaled_error = [](const double& raw_cost,const std::pair<double,double>& range,bool& below_min)
00202 {
00203 below_min = false;
00204
00205
00206 if(raw_cost > range.second)
00207 {
00208 return 1.0;
00209 }
00210
00211
00212 if(raw_cost >= range.first)
00213 {
00214 return raw_cost/(range.second - range.first);
00215 }
00216
00217
00218 below_min = true;
00219 return 0.0;
00220 };
00221
00222 costs.resize(parameters.cols());
00223 costs.setConstant(0.0);
00224
00225 last_joint_pose_ = parameters.rightCols(1);
00226 state_->setJointGroupPositions(group_name_,last_joint_pose_);
00227 last_tool_pose_ = state_->getGlobalLinkTransform(tool_link_);
00228
00229 computeTwist(last_tool_pose_,tool_goal_pose_,dof_nullity_,tool_twist_error_);
00230
00231 double pos_error = tool_twist_error_.segment(0,3).norm();
00232 double orientation_error = tool_twist_error_.segment(3,3).norm();
00233
00234
00235
00236 bool valid;
00237 pos_error = compute_scaled_error(pos_error,position_error_range_,valid);
00238 validity &= valid;
00239
00240 orientation_error = compute_scaled_error(orientation_error,orientation_error_range_,valid);
00241 validity &= valid;
00242
00243 costs(costs.size()-1) = pos_error*position_cost_weight_ + orientation_error * orientation_cost_weight_;
00244
00245 return true;
00246 }
00247
00248 }
00249 }