obstacle_distance_gradient.cpp
Go to the documentation of this file.
1 
28 #include <ros/console.h>
31 
33 static const double LONGEST_VALID_JOINT_MOVE = 0.01;
34 
35 namespace stomp_moveit
36 {
37 namespace cost_functions
38 {
39 
40 ObstacleDistanceGradient::ObstacleDistanceGradient() :
41  name_("ObstacleDistanceGradient"),
42  robot_state_()
43 {
44 
45 }
46 
47 ObstacleDistanceGradient::~ObstacleDistanceGradient()
48 {
49 
50 }
51 
52 bool ObstacleDistanceGradient::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
53  const std::string& group_name, XmlRpc::XmlRpcValue& config)
54 {
55  robot_model_ptr_ = robot_model_ptr;
56  group_name_ = group_name;
57  collision_request_.distance = true;
58  collision_request_.group_name = group_name;
59  collision_request_.cost = false;
60  collision_request_.max_contacts = 1;
61  collision_request_.max_contacts_per_pair = 1;
62  collision_request_.contacts = false;
63  collision_request_.verbose = false;
64  return configure(config);
65 }
66 
67 bool ObstacleDistanceGradient::configure(const XmlRpc::XmlRpcValue& config)
68 {
69 
70  try
71  {
72  // check parameter presence
73  auto members = {"cost_weight" ,"max_distance"};
74  for(auto& m : members)
75  {
76  if(!config.hasMember(m))
77  {
78  ROS_ERROR("%s failed to find the '%s' parameter",getName().c_str(),m);
79  return false;
80  }
81  }
82 
83  XmlRpc::XmlRpcValue c = config;
84  max_distance_ = static_cast<double>(c["max_distance"]);
85  cost_weight_ = static_cast<double>(c["cost_weight"]);
86  longest_valid_joint_move_ = c.hasMember("longest_valid_joint_move") ? static_cast<double>(c["longest_valid_joint_move"]):LONGEST_VALID_JOINT_MOVE;
87 
88  if(!c.hasMember("longest_valid_joint_move"))
89  {
90  ROS_WARN("%s using default value for 'longest_valid_joint_move' of %f",getName().c_str(),longest_valid_joint_move_);
91  }
92  }
93  catch(XmlRpc::XmlRpcException& e)
94  {
95  ROS_ERROR("%s failed to parse configuration parameters",name_.c_str());
96  return false;
97  }
98 
99  return true;
100 }
101 
102 bool ObstacleDistanceGradient::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
103  const moveit_msgs::MotionPlanRequest &req,
104  const stomp_core::StompConfiguration &config,
105  moveit_msgs::MoveItErrorCodes& error_code)
106 {
107  using namespace moveit::core;
108 
109  planning_scene_ = planning_scene;
110  plan_request_ = req;
111  error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
112 
113  // storing robot state
114  robot_state_.reset(new RobotState(robot_model_ptr_));
115 
116  if(!robotStateMsgToRobotState(req.start_state,*robot_state_,true))
117  {
118  ROS_ERROR("%s Failed to get current robot state from request",getName().c_str());
119  return false;
120  }
121 
122  // copying into intermediate robot states
123  for(auto& rs : intermediate_coll_states_)
124  {
125  rs.reset(new RobotState(*robot_state_));
126  }
127 
128  return true;
129 }
130 
131 bool ObstacleDistanceGradient::computeCosts(const Eigen::MatrixXd& parameters, std::size_t start_timestep,
132  std::size_t num_timesteps, int iteration_number, int rollout_number,
133  Eigen::VectorXd& costs, bool& validity)
134 {
135 
136  if(!robot_state_)
137  {
138  ROS_ERROR("%s Robot State has not been updated",getName().c_str());
139  return false;
140  }
141 
142 
143 
144  // allocating
145  costs = Eigen::VectorXd::Zero(num_timesteps);
146  const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);
147 
148  if(parameters.cols()<start_timestep + num_timesteps)
149  {
150  ROS_ERROR_STREAM("Size in the 'parameters' matrix is less than required");
151  return false;
152  }
153 
154  // request the distance at each state
155  double dist;
156  bool skip_next_check = false;
157  validity = true;
158  for (auto t=start_timestep; t<start_timestep + num_timesteps; ++t)
159  {
160 
161  if(!skip_next_check)
162  {
163  collision_result_.clear();
164  robot_state_->setJointGroupPositions(joint_group,parameters.col(t));
165  robot_state_->update();
166  collision_result_.distance = max_distance_;
167 
168  planning_scene_->checkSelfCollision(collision_request_,collision_result_,*robot_state_,planning_scene_->getAllowedCollisionMatrix());
169  dist = collision_result_.collision ? -1.0 :collision_result_.distance ;
170 
171  if(dist >= max_distance_)
172  {
173  costs(t) = 0; // away from obstacle
174  }
175  else if(dist < 0)
176  {
177  costs(t) = 1.0; // in collision
178  validity = false;
179  }
180  else
181  {
182  costs(t) = (max_distance_ - dist)/max_distance_;
183  }
184  }
185 
186  skip_next_check = false;
187 
188  // check intermediate poses to the next position (skip the last one)
189  if(t < start_timestep + num_timesteps - 1)
190  {
191  if(!checkIntermediateCollisions(parameters.col(t),parameters.col(t+1),longest_valid_joint_move_))
192  {
193  costs(t) = 1.0;
194  costs(t+1) = 1.0;
195  validity = false;
196  skip_next_check = true;
197  }
198  else
199  {
200  skip_next_check = false;
201  }
202  }
203 
204  }
205 
206  return true;
207 }
208 
209 bool ObstacleDistanceGradient::checkIntermediateCollisions(const Eigen::VectorXd& start,
210  const Eigen::VectorXd& end,double longest_valid_joint_move)
211 {
212  Eigen::VectorXd diff = end - start;
213  int num_intermediate = std::ceil(((diff.cwiseAbs())/longest_valid_joint_move).maxCoeff()) - 1;
214  if(num_intermediate < 1.0)
215  {
216  // no interpolation needed
217  return true;
218  }
219 
220  // grabbing states
221  auto& start_state = intermediate_coll_states_[0];
222  auto& mid_state = intermediate_coll_states_[1];
223  auto& end_state = intermediate_coll_states_[2];
224 
225  if(!start_state || !mid_state || !end_state)
226  {
227  ROS_ERROR("%s intermediate states not initialized",getName().c_str());
228  return false;
229  }
230 
231  // setting up collision
232  auto req = collision_request_;
233  req.distance = false;
235  const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);
236  start_state->setJointGroupPositions(joint_group,start);
237  end_state->setJointGroupPositions(joint_group,end);
238 
239  // checking intermediate states
240  double dt = 1.0/static_cast<double>(num_intermediate);
241  double interval = 0.0;
242  for(std::size_t i = 1; i < num_intermediate;i++)
243  {
244  interval = i*dt;
245  start_state->interpolate(*end_state,interval,*mid_state) ;
246  if(planning_scene_->isStateColliding(*mid_state))
247  {
248  return false;
249  }
250  }
251 
252  return true;
253 }
254 
255 void ObstacleDistanceGradient::done(bool success,int total_iterations,double final_cost,const Eigen::MatrixXd& parameters)
256 {
257  robot_state_.reset();
258 }
259 
260 } /* namespace cost_functions */
261 } /* namespace stomp_moveit */
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
std::string getName(void *handle)
#define ROS_WARN(...)
PLUGINLIB_EXPORT_CLASS(test_moveit_controller_manager::TestMoveItControllerManager, moveit_controller_manager::MoveItControllerManager)
double dist(const T &p1, const T &p2)
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
bool hasMember(const std::string &name) const
This defines a Robot Model for the Stomp Planner.
Assigns a cost value to each robot state by evaluating the minimum distance between the robot and the...
#define ROS_ERROR_STREAM(args)
virtual bool configure(const XmlRpc::XmlRpcValue &config) override
see base class for documentation
#define ROS_ERROR(...)


stomp_moveit
Author(s): Jorge Nicho
autogenerated on Fri May 8 2020 03:35:47