33 static const
int MIN_KERNEL_WINDOW_SIZE = 3;
43 using namespace Eigen;
46 window_size = 2*(window_size/2) + 1;
47 smoothed.setZero(data.size());
48 VectorXd x_nneighbors = VectorXd::Zero(window_size);
49 VectorXd y_nneighbors = VectorXd::Zero(window_size);
50 VectorXd kernel_weights = VectorXd::Zero(window_size);
54 int index_left, index_right;
55 std::size_t window_index_middle = window_size/2;
59 auto epanechnikov_function = [](
double x_m,
const VectorXd& neighbors,
double lambda, VectorXd& weights )
63 for(
int i = 0; i < neighbors.size(); i++)
65 t = std::abs(x_m - neighbors(i))/lambda;
68 weights(i) = 0.75f*(1 - std::pow(t,2));
78 for(
int i = 0; i < data.size(); i++)
81 x_nneighbors(window_index_middle) = i;
82 y_nneighbors(window_index_middle) = data(i);
85 for(
int j = 1; j <= window_size/2; j++)
92 x_nneighbors(window_index_middle - j) = 0;
93 y_nneighbors(window_index_middle - j) = data(0);
97 x_nneighbors(window_index_middle - j) = index_left;
98 y_nneighbors(window_index_middle - j) = data(index_left);
101 if(index_right > data.rows()-1)
103 x_nneighbors(window_index_middle + j) = data.rows()-1;
104 y_nneighbors(window_index_middle + j) = data(data.rows() - 1);
108 x_nneighbors(window_index_middle + j) = index_right;
109 y_nneighbors(window_index_middle + j) = data(index_right);
114 epanechnikov_function(i,x_nneighbors,window_size,kernel_weights);
115 smoothed(i) = (y_nneighbors.array()*kernel_weights.array()).sum()/kernel_weights.sum();
123 namespace cost_functions
126 CollisionCheck::CollisionCheck():
127 name_(
"CollisionCheckPlugin"),
129 collision_penalty_(0.0)
135 CollisionCheck::~CollisionCheck()
140 bool CollisionCheck::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
143 robot_model_ptr_ = robot_model_ptr;
144 group_name_ = group_name;
145 return configure(config);
148 bool CollisionCheck::setMotionPlanRequest(
const planning_scene::PlanningSceneConstPtr&
planning_scene,
149 const moveit_msgs::MotionPlanRequest &req,
151 moveit_msgs::MoveItErrorCodes& error_code)
155 planning_scene_ = planning_scene;
157 error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
160 robot_state_.reset(
new RobotState(robot_model_ptr_));
163 ROS_ERROR(
"%s Failed to get current robot state from request",
getName().c_str());
168 for(
auto& rs : intermediate_coll_states_)
180 bool CollisionCheck::computeCosts(
const Eigen::MatrixXd& parameters,
181 std::size_t start_timestep,
182 std::size_t num_timesteps,
183 int iteration_number,
185 Eigen::VectorXd& costs,
190 using namespace Eigen;
199 typedef ContactMap::iterator ContactMapIterator;
200 typedef std::vector<collision_detection::Contact> ContactArray;
203 costs = Eigen::VectorXd::Zero(num_timesteps);
206 raw_costs_.setZero();
212 const JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);
214 if(parameters.cols()< (start_timestep + num_timesteps))
221 bool skip_next_check =
false;
222 for (
auto t=start_timestep; t<start_timestep + num_timesteps; ++t)
226 robot_state_->setJointGroupPositions(joint_group,parameters.col(t));
227 robot_state_->update();
229 if (planning_scene_->isStateColliding(*robot_state_, group_name_))
231 raw_costs_(t) = collision_penalty_;
237 if(t < start_timestep + num_timesteps - 1)
239 if(!checkIntermediateCollisions(parameters.col(t),parameters.col(t+1),longest_valid_joint_move_))
241 raw_costs_(t) = collision_penalty_;
242 raw_costs_(t+1) = collision_penalty_;
244 skip_next_check =
true;
248 skip_next_check =
false;
257 if(kernel_window_percentage_> 1e-6)
259 int window_size = num_timesteps*kernel_window_percentage_;
260 window_size = window_size < MIN_KERNEL_WINDOW_SIZE ? MIN_KERNEL_WINDOW_SIZE : window_size;
263 intermediate_costs_slots_ = (raw_costs_.array() < collision_penalty_).cast<double>();
264 raw_costs_ += (raw_costs_.sum()/raw_costs_.size())*(intermediate_costs_slots_.matrix());
279 bool CollisionCheck::checkIntermediateCollisions(
const Eigen::VectorXd& start,
280 const Eigen::VectorXd& end,
double longest_valid_joint_move)
282 Eigen::VectorXd
diff = end - start;
283 int num_intermediate = std::ceil(((diff.cwiseAbs())/longest_valid_joint_move).maxCoeff()) - 1;
284 if(num_intermediate < 1.0)
291 auto& start_state = intermediate_coll_states_[0];
292 auto& mid_state = intermediate_coll_states_[1];
293 auto& end_state = intermediate_coll_states_[2];
295 if(!start_state || !mid_state || !end_state)
303 start_state->setJointGroupPositions(joint_group,start);
304 end_state->setJointGroupPositions(joint_group,end);
307 double dt = 1.0/
static_cast<double>(num_intermediate);
308 double interval = 0.0;
309 for(std::size_t i = 1; i < num_intermediate;i++)
312 start_state->interpolate(*end_state,interval,*mid_state) ;
313 if(planning_scene_->isStateColliding(*mid_state, group_name_))
326 auto members = {
"cost_weight",
"collision_penalty",
"kernel_window_percentage"};
327 for(
auto& m : members)
331 ROS_ERROR(
"%s failed to find one or more required parameters",
getName().c_str());
339 auto members = {
"cost_weight",
"collision_penalty",
"kernel_window_percentage",
"longest_valid_joint_move"};
340 for(
auto& m : members)
350 cost_weight_ =
static_cast<double>(c[
"cost_weight"]);
351 collision_penalty_ =
static_cast<double>(c[
"collision_penalty"]);
352 kernel_window_percentage_ =
static_cast<double>(c[
"kernel_window_percentage"]);
353 longest_valid_joint_move_ =
static_cast<double>(c[
"longest_valid_joint_move"]);
357 ROS_ERROR(
"%s failed to parse configuration parameters",name_.c_str());
364 void CollisionCheck::done(
bool success,
int total_iterations,
double final_cost,
const Eigen::MatrixXd& parameters)
366 robot_state_.reset();
This defines a cost function for collision checking.
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
std::string getName(void *handle)
std::map< std::pair< std::string, std::string >, std::vector< Contact > > ContactMap
PLUGINLIB_EXPORT_CLASS(test_moveit_controller_manager::TestMoveItControllerManager, moveit_controller_manager::MoveItControllerManager)
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
static void applyKernelSmoothing(std::size_t window_size, const Eigen::VectorXd &data, Eigen::VectorXd &smoothed)
Convenience method that propagates the cost value at center to the window to the adjacent points...
Assigns a cost value to each robot state by evaluating if the robot is in collision.
bool hasMember(const std::string &name) const
Assigns a cost value to each robot state by evaluating the minimum distance between the robot and the...
#define ROS_ERROR_STREAM(args)