00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include <chomp_motion_planner/chomp_optimizer.h>
00038 #include <ros/ros.h>
00039 #include <visualization_msgs/MarkerArray.h>
00040 #include <chomp_motion_planner/chomp_utils.h>
00041 #include <Eigen/LU>
00042
00043 using namespace std;
00044 USING_PART_OF_NAMESPACE_EIGEN
00045
00046 namespace chomp
00047 {
00048
00049 ChompOptimizer::ChompOptimizer(ChompTrajectory *trajectory, const ChompRobotModel *robot_model,
00050 const ChompRobotModel::ChompPlanningGroup *planning_group, const ChompParameters *parameters,
00051 const ros::Publisher& vis_marker_array_publisher,
00052 const ros::Publisher& vis_marker_publisher,
00053 ChompCollisionSpace *collision_space):
00054 full_trajectory_(trajectory),
00055 robot_model_(robot_model),
00056 planning_group_(planning_group),
00057 parameters_(parameters),
00058 collision_space_(collision_space),
00059 group_trajectory_(*full_trajectory_, planning_group_, DIFF_RULE_LENGTH),
00060 kdl_joint_array_(robot_model_->getKDLTree()->getNrOfJoints()),
00061 vis_marker_array_pub_(vis_marker_array_publisher),
00062 vis_marker_pub_(vis_marker_publisher)
00063 {
00064 initialize();
00065 }
00066
00067 void ChompOptimizer::initialize()
00068 {
00069
00070
00071 num_vars_free_ = group_trajectory_.getNumFreePoints();
00072 num_vars_all_ = group_trajectory_.getNumPoints();
00073 num_joints_ = group_trajectory_.getNumJoints();
00074
00075 free_vars_start_ = group_trajectory_.getStartIndex();
00076 free_vars_end_ = group_trajectory_.getEndIndex();
00077
00078
00079
00080
00081 group_joint_to_kdl_joint_index_.resize(num_joints_);
00082 for (int i=0; i<num_joints_; ++i)
00083 group_joint_to_kdl_joint_index_[i] = planning_group_->chomp_joints_[i].kdl_joint_index_;
00084
00085 num_collision_points_ = planning_group_->collision_points_.size();
00086
00087
00088 joint_costs_.reserve(num_joints_);
00089
00090 double max_cost_scale = 0.0;
00091 ros::NodeHandle nh("~");
00092 for (int i=0; i<num_joints_; i++)
00093 {
00094 double joint_cost = 1.0;
00095 std::string joint_name = planning_group_->chomp_joints_[i].joint_name_;
00096 nh.param("joint_costs/"+joint_name, joint_cost, 1.0);
00097 std::vector<double> derivative_costs(3);
00098 derivative_costs[0] = joint_cost*parameters_->getSmoothnessCostVelocity();
00099 derivative_costs[1] = joint_cost*parameters_->getSmoothnessCostAcceleration();
00100 derivative_costs[2] = joint_cost*parameters_->getSmoothnessCostJerk();
00101
00102
00103 joint_costs_.push_back(ChompCost(group_trajectory_, i, derivative_costs, parameters_->getRidgeFactor()));
00104 double cost_scale = joint_costs_[i].getMaxQuadCostInvValue();
00105 if (max_cost_scale < cost_scale)
00106 max_cost_scale = cost_scale;
00107 }
00108
00109
00110 for (int i=0; i<num_joints_; i++)
00111 {
00112 joint_costs_[i].scale(max_cost_scale);
00113 }
00114
00115
00116 smoothness_increments_ = Eigen::MatrixXd::Zero(num_vars_free_, num_joints_);
00117 collision_increments_ = Eigen::MatrixXd::Zero(num_vars_free_, num_joints_);
00118 final_increments_ = Eigen::MatrixXd::Zero(num_vars_free_, num_joints_);
00119 smoothness_derivative_ = Eigen::VectorXd::Zero(num_vars_all_);
00120 jacobian_ = Eigen::MatrixXd::Zero(3, num_joints_);
00121 jacobian_pseudo_inverse_ = Eigen::MatrixXd::Zero(num_joints_, 3);
00122 jacobian_jacobian_tranpose_ = Eigen::MatrixXd::Zero(3, 3);
00123 random_state_ = Eigen::VectorXd::Zero(num_joints_);
00124 joint_state_velocities_ = Eigen::VectorXd::Zero(num_joints_);
00125
00126 group_trajectory_backup_ = group_trajectory_.getTrajectory();
00127 best_group_trajectory_ = group_trajectory_.getTrajectory();
00128
00129 joint_axis_.resize(num_vars_all_, std::vector<KDL::Vector>(robot_model_->getKDLTree()->getNrOfJoints()));
00130 joint_pos_.resize(num_vars_all_, std::vector<KDL::Vector>(robot_model_->getKDLTree()->getNrOfJoints()));
00131 segment_frames_.resize(num_vars_all_, std::vector<KDL::Frame>(robot_model_->getKDLTree()->getNrOfSegments()));
00132 collision_point_pos_.resize(num_vars_all_, std::vector<KDL::Vector>(num_collision_points_));
00133 collision_point_vel_.resize(num_vars_all_, std::vector<KDL::Vector>(num_collision_points_));
00134 collision_point_acc_.resize(num_vars_all_, std::vector<KDL::Vector>(num_collision_points_));
00135
00136 collision_point_potential_.resize(num_vars_all_, std::vector<double>(num_collision_points_));
00137 collision_point_vel_mag_.resize(num_vars_all_, std::vector<double>(num_collision_points_));
00138 collision_point_potential_gradient_.resize(num_vars_all_, std::vector<Eigen::Vector3d>(num_collision_points_));
00139
00140
00141 kdlVecVecToEigenVecVec(joint_axis_, joint_axis_eigen_, 3, 1);
00142 kdlVecVecToEigenVecVec(joint_pos_, joint_pos_eigen_, 3, 1);
00143 kdlVecVecToEigenVecVec(collision_point_pos_, collision_point_pos_eigen_, 3, 1);
00144 kdlVecVecToEigenVecVec(collision_point_vel_, collision_point_vel_eigen_, 3, 1);
00145 kdlVecVecToEigenVecVec(collision_point_acc_, collision_point_acc_eigen_, 3, 1);
00146
00147 collision_free_iteration_ = 0;
00148 is_collision_free_ = false;
00149 state_is_in_collision_.resize(num_vars_all_);
00150 point_is_in_collision_.resize(num_vars_all_, std::vector<int>(num_collision_points_));
00151
00152 last_improvement_iteration_ = -1;
00153
00154
00155 momentum_ = Eigen::MatrixXd::Zero(num_vars_free_, num_joints_);
00156 random_momentum_ = Eigen::MatrixXd::Zero(num_vars_free_, num_joints_);
00157 random_joint_momentum_ = Eigen::VectorXd::Zero(num_vars_free_);
00158 multivariate_gaussian_.clear();
00159 stochasticity_factor_ = 1.0;
00160 for (int i=0; i<num_joints_; i++)
00161 {
00162 multivariate_gaussian_.push_back(MultivariateGaussian(Eigen::VectorXd::Zero(num_vars_free_), joint_costs_[i].getQuadraticCostInverse()));
00163 }
00164
00165
00166 animate_endeffector_segment_number_ = robot_model_->getForwardKinematicsSolver()->segmentNameToIndex(parameters_->getAnimateEndeffectorSegment());
00167
00168 }
00169
00170 ChompOptimizer::~ChompOptimizer()
00171 {
00172 }
00173
00174 void ChompOptimizer::optimize()
00175 {
00176 ros::WallTime start_time = ros::WallTime::now();
00177
00178 collision_space_->lock();
00179
00180 if (parameters_->getAnimatePath())
00181 {
00182 animatePath();
00183 }
00184
00185
00186 for (iteration_=0; iteration_<parameters_->getMaxIterations(); iteration_++)
00187 {
00188 performForwardKinematics();
00189 double cost = getTrajectoryCost();
00190
00191 if (iteration_==0)
00192 {
00193 best_group_trajectory_ = group_trajectory_.getTrajectory();
00194 best_group_trajectory_cost_ = cost;
00195 }
00196 else
00197 {
00198 if (cost < best_group_trajectory_cost_)
00199 {
00200 best_group_trajectory_ = group_trajectory_.getTrajectory();
00201 best_group_trajectory_cost_ = cost;
00202 last_improvement_iteration_ = iteration_;
00203 }
00204 }
00205
00206 calculateSmoothnessIncrements();
00207 calculateCollisionIncrements();
00208 calculateTotalIncrements();
00209
00210 if (!parameters_->getUseHamiltonianMonteCarlo())
00211 {
00212
00213 addIncrementsToTrajectory();
00214 }
00215 else
00216 {
00217
00218 getRandomMomentum();
00219 updateMomentum();
00220 updatePositionFromMomentum();
00221 stochasticity_factor_ *= parameters_->getHmcAnnealingFactor();
00222 }
00223
00224 handleJointLimits();
00225 updateFullTrajectory();
00226 if (iteration_%10==0)
00227 ROS_DEBUG("Trajectory cost: %f (s=%f, c=%f)", getTrajectoryCost(), getSmoothnessCost(), getCollisionCost());
00228 if (collision_free_iteration_ >= parameters_->getMaxIterationsAfterCollisionFree())
00229 {
00230 iteration_++;
00231 break;
00232 }
00233
00234 if (!is_collision_free_ && parameters_->getAddRandomness())
00235 {
00236 performForwardKinematics();
00237 double original_cost = getTrajectoryCost();
00238 group_trajectory_backup_ = group_trajectory_.getTrajectory();
00239 perturbTrajectory();
00240 handleJointLimits();
00241 updateFullTrajectory();
00242 performForwardKinematics();
00243 double new_cost = getTrajectoryCost();
00244 if (new_cost < original_cost)
00245 {
00246
00247 }
00248 else
00249 {
00250
00251 group_trajectory_.getTrajectory() = group_trajectory_backup_;
00252 updateFullTrajectory();
00253 }
00254
00255 }
00256
00257 if (parameters_->getAnimateEndeffector())
00258 {
00259 animateEndeffector();
00260 }
00261
00262 if (parameters_->getAnimatePath() && iteration_%25 == 0)
00263 {
00264 animatePath();
00265 }
00266
00267 }
00268 ROS_INFO_STREAM("We think the path is collision free: " << is_collision_free_);
00269
00270 if (parameters_->getAnimatePath())
00271 {
00272 animatePath();
00273 }
00274
00275 group_trajectory_.getTrajectory() = best_group_trajectory_;
00276 updateFullTrajectory();
00277
00278 collision_space_->unlock();
00279 if (parameters_->getAnimatePath())
00280 animatePath();
00281
00282 ROS_INFO("Terminated after %d iterations, using path from iteration %d", iteration_, last_improvement_iteration_);
00283 ROS_INFO("Optimization core finished in %f sec", (ros::WallTime::now() - start_time).toSec());
00284 }
00285
00286 void ChompOptimizer::calculateSmoothnessIncrements()
00287 {
00288 for (int i=0; i<num_joints_; i++)
00289 {
00290 joint_costs_[i].getDerivative(group_trajectory_.getJointTrajectory(i), smoothness_derivative_);
00291 smoothness_increments_.col(i) = -smoothness_derivative_.segment(
00292 group_trajectory_.getStartIndex(), num_vars_free_);
00293 }
00294 }
00295
00296 void ChompOptimizer::calculateCollisionIncrements()
00297 {
00298 double potential;
00299 double vel_mag_sq;
00300 double vel_mag;
00301 Vector3d potential_gradient;
00302 Vector3d normalized_velocity;
00303 Matrix3d orthogonal_projector;
00304 Vector3d curvature_vector;
00305 Vector3d cartesian_gradient;
00306
00307 collision_increments_.setZero(num_vars_free_, num_joints_);
00308 for (int i=free_vars_start_; i<=free_vars_end_; i++)
00309 {
00310 for (int j=0; j<num_collision_points_; j++)
00311 {
00312 potential = collision_point_potential_[i][j];
00313 if (potential <= 1e-10)
00314 continue;
00315
00316 potential_gradient = collision_point_potential_gradient_[i][j];
00317
00318 vel_mag = collision_point_vel_mag_[i][j];
00319 vel_mag_sq = vel_mag*vel_mag;
00320
00321
00322
00323 normalized_velocity = collision_point_vel_eigen_[i][j] / vel_mag;
00324 orthogonal_projector = Matrix3d::Identity() - (normalized_velocity * normalized_velocity.transpose());
00325 curvature_vector = (orthogonal_projector * collision_point_acc_eigen_[i][j]) / vel_mag_sq;
00326 cartesian_gradient = vel_mag*(orthogonal_projector*potential_gradient - potential*curvature_vector);
00327
00328
00329 planning_group_->collision_points_[j].getJacobian(joint_pos_eigen_[i], joint_axis_eigen_[i],
00330 collision_point_pos_eigen_[i][j], jacobian_, group_joint_to_kdl_joint_index_);
00331 if (parameters_->getUsePseudoInverse())
00332 {
00333 calculatePseudoInverse();
00334 collision_increments_.row(i-free_vars_start_).transpose() -=
00335 jacobian_pseudo_inverse_ * cartesian_gradient;
00336 }
00337 else
00338 {
00339 collision_increments_.row(i-free_vars_start_).transpose() -=
00340 jacobian_.transpose() * cartesian_gradient;
00341 }
00342 if (point_is_in_collision_[i][j])
00343 break;
00344 }
00345 }
00346
00347 }
00348
00349 void ChompOptimizer::calculatePseudoInverse()
00350 {
00351 jacobian_jacobian_tranpose_ = jacobian_*jacobian_.transpose() + Eigen::MatrixXd::Identity(3,3)*parameters_->getPseudoInverseRidgeFactor();
00352 jacobian_pseudo_inverse_ = jacobian_.transpose() * jacobian_jacobian_tranpose_.inverse();
00353 }
00354
00355 void ChompOptimizer::calculateTotalIncrements()
00356 {
00357 for (int i=0; i<num_joints_; i++)
00358 {
00359 final_increments_.col(i) = parameters_->getLearningRate() *
00360 (
00361 joint_costs_[i].getQuadraticCostInverse() *
00362 (
00363 parameters_->getSmoothnessCostWeight() * smoothness_increments_.col(i) +
00364 parameters_->getObstacleCostWeight() * collision_increments_.col(i)
00365 )
00366 );
00367 }
00368
00369 }
00370
00371 void ChompOptimizer::addIncrementsToTrajectory()
00372 {
00373
00374 for (int i=0; i<num_joints_; i++)
00375 {
00376 double scale = 1.0;
00377 double max = final_increments_.col(i).maxCoeff();
00378 double min = final_increments_.col(i).minCoeff();
00379 double max_scale = planning_group_->chomp_joints_[i].joint_update_limit_ / fabs(max);
00380 double min_scale = planning_group_->chomp_joints_[i].joint_update_limit_ / fabs(min);
00381 if (max_scale < scale)
00382 scale = max_scale;
00383 if (min_scale < scale)
00384 scale = min_scale;
00385 group_trajectory_.getFreeTrajectoryBlock().col(i) += scale * final_increments_.col(i);
00386 }
00387
00388
00389 }
00390
00391 void ChompOptimizer::updateFullTrajectory()
00392 {
00393 full_trajectory_->updateFromGroupTrajectory(group_trajectory_);
00394 }
00395
00396 void ChompOptimizer::debugCost()
00397 {
00398 double cost = 0.0;
00399 for (int i=0; i<num_joints_; i++)
00400 cost += joint_costs_[i].getCost(group_trajectory_.getJointTrajectory(i));
00401 cout << "Cost = " << cost << endl;
00402 }
00403
00404 double ChompOptimizer::getTrajectoryCost()
00405 {
00406 return getSmoothnessCost() + getCollisionCost();
00407 }
00408
00409 double ChompOptimizer::getSmoothnessCost()
00410 {
00411 double smoothness_cost = 0.0;
00412
00413 for (int i=0; i<num_joints_; i++)
00414 smoothness_cost += joint_costs_[i].getCost(group_trajectory_.getJointTrajectory(i));
00415
00416 return parameters_->getSmoothnessCostWeight() * smoothness_cost;
00417 }
00418
00419 double ChompOptimizer::getCollisionCost()
00420 {
00421 double collision_cost = 0.0;
00422
00423 double worst_collision_cost = 0.0;
00424 worst_collision_cost_state_ = -1;
00425
00426
00427 for (int i=free_vars_start_; i<=free_vars_end_; i++)
00428 {
00429 double state_collision_cost = 0.0;
00430 for (int j=0; j<num_collision_points_; j++)
00431 {
00432 state_collision_cost += collision_point_potential_[i][j] * collision_point_vel_mag_[i][j];
00433 }
00434 collision_cost += state_collision_cost;
00435 if (state_collision_cost > worst_collision_cost)
00436 {
00437 worst_collision_cost = state_collision_cost;
00438 worst_collision_cost_state_ = i;
00439 }
00440 }
00441
00442 return parameters_->getObstacleCostWeight() * collision_cost;
00443 }
00444
00445 void ChompOptimizer::handleJointLimits()
00446 {
00447 for (int joint=0; joint<num_joints_; joint++)
00448 {
00449 if (!planning_group_->chomp_joints_[joint].has_joint_limits_)
00450 continue;
00451
00452 double joint_max = planning_group_->chomp_joints_[joint].joint_limit_max_;
00453 double joint_min = planning_group_->chomp_joints_[joint].joint_limit_min_;
00454
00455 int count = 0;
00456
00457 bool violation = false;
00458 do
00459 {
00460 double max_abs_violation = 1e-6;
00461 double max_violation = 0.0;
00462 int max_violation_index = 0;
00463 violation = false;
00464 for (int i=free_vars_start_; i<=free_vars_end_; i++)
00465 {
00466 double amount = 0.0;
00467 double absolute_amount = 0.0;
00468 if (group_trajectory_(i, joint) > joint_max)
00469 {
00470 amount = joint_max - group_trajectory_(i, joint);
00471 absolute_amount = fabs(amount);
00472 }
00473 else if (group_trajectory_(i, joint) < joint_min)
00474 {
00475 amount = joint_min - group_trajectory_(i, joint);
00476 absolute_amount = fabs(amount);
00477 }
00478 if (absolute_amount > max_abs_violation)
00479 {
00480 max_abs_violation = absolute_amount;
00481 max_violation = amount;
00482 max_violation_index = i;
00483 violation = true;
00484 }
00485 }
00486
00487 if (violation)
00488 {
00489 int free_var_index = max_violation_index - free_vars_start_;
00490 double multiplier = max_violation / joint_costs_[joint].getQuadraticCostInverse()(free_var_index,free_var_index);
00491 group_trajectory_.getFreeJointTrajectoryBlock(joint) +=
00492 multiplier * joint_costs_[joint].getQuadraticCostInverse().col(free_var_index);
00493 }
00494 if (++count > 10)
00495 break;
00496 }
00497 while(violation);
00498 }
00499 }
00500
00501 void ChompOptimizer::performForwardKinematics()
00502 {
00503 double invTime = 1.0 / group_trajectory_.getDiscretization();
00504 double invTimeSq = invTime*invTime;
00505
00506
00507 int start = free_vars_start_;
00508 int end = free_vars_end_;
00509 if (iteration_==0)
00510 {
00511 start = 0;
00512 end = num_vars_all_-1;
00513 }
00514
00515 is_collision_free_ = true;
00516
00517
00518 for (int i=start; i<=end; ++i)
00519 {
00520 int full_traj_index = group_trajectory_.getFullTrajectoryIndex(i);
00521 full_trajectory_->getTrajectoryPointKDL(full_traj_index, kdl_joint_array_);
00522
00523
00524
00525
00526
00527
00528 if (iteration_==0)
00529 {
00530 planning_group_->fk_solver_->JntToCartFull(kdl_joint_array_, joint_pos_[i], joint_axis_[i], segment_frames_[i]);
00531 }
00532 else
00533 {
00534 planning_group_->fk_solver_->JntToCartPartial(kdl_joint_array_, joint_pos_[i], joint_axis_[i], segment_frames_[i]);
00535 }
00536
00537
00538
00539 state_is_in_collision_[i] = false;
00540
00541
00542 for (int j=0; j<num_collision_points_; j++)
00543 {
00544 planning_group_->collision_points_[j].getTransformedPosition(segment_frames_[i], collision_point_pos_[i][j]);
00545
00546
00547
00548 bool colliding = collision_space_->getCollisionPointPotentialGradient(planning_group_->collision_points_[j],
00549 collision_point_pos_eigen_[i][j],
00550 collision_point_potential_[i][j],
00551 collision_point_potential_gradient_[i][j]);
00552
00553 point_is_in_collision_[i][j] = colliding;
00554
00555 if (colliding)
00556 state_is_in_collision_[i] = true;
00557 }
00558
00559 if (state_is_in_collision_[i])
00560 {
00561 is_collision_free_ = false;
00562 }
00563 }
00564
00565
00566 for (int i=free_vars_start_; i<=free_vars_end_; i++)
00567 {
00568 for (int j=0; j<num_collision_points_; j++)
00569 {
00570 SetToZero(collision_point_vel_[i][j]);
00571 SetToZero(collision_point_acc_[i][j]);
00572 for (int k=-DIFF_RULE_LENGTH/2; k<=DIFF_RULE_LENGTH/2; k++)
00573 {
00574 collision_point_vel_[i][j] += (invTime * DIFF_RULES[0][k+DIFF_RULE_LENGTH/2]) *
00575 collision_point_pos_[i+k][j];
00576 collision_point_acc_[i][j] += (invTimeSq * DIFF_RULES[1][k+DIFF_RULE_LENGTH/2]) *
00577 collision_point_pos_[i+k][j];
00578 }
00579
00580 collision_point_vel_mag_[i][j] = collision_point_vel_eigen_[i][j].norm();
00581 }
00582 }
00583
00584 if (is_collision_free_)
00585 collision_free_iteration_++;
00586 else
00587 collision_free_iteration_ = 0;
00588
00589 }
00590
00591 void ChompOptimizer::eigenMapTest()
00592 {
00593 double foo_eigen;
00594 double foo_kdl;
00595
00596 cout << "Eigen location: " << &(joint_axis_eigen_[free_vars_start_][0](0)) <<
00597 " KDL location: " << &(joint_axis_[free_vars_start_][0](0)) << endl;
00598
00599 foo_eigen = joint_axis_eigen_[free_vars_start_][0](0);
00600 foo_kdl = joint_axis_[free_vars_start_][0](0);
00601 printf("eigen = %f, kdl = %f\n", foo_eigen, foo_kdl);
00602 ROS_ASSERT(foo_eigen==foo_kdl);
00603
00604 joint_axis_eigen_[free_vars_start_][0](0) = 1.0;
00605 foo_eigen = joint_axis_eigen_[free_vars_start_][0](0);
00606 foo_kdl = joint_axis_[free_vars_start_][0](0);
00607 printf("eigen = %f, kdl = %f\n", foo_eigen, foo_kdl);
00608 ROS_ASSERT(foo_kdl == foo_eigen);
00609
00610 joint_axis_[free_vars_start_][0](0) = 2.0;
00611 foo_eigen = joint_axis_eigen_[free_vars_start_][0](0);
00612 foo_kdl = joint_axis_[free_vars_start_][0](0);
00613 printf("eigen = %f, kdl = %f\n", foo_eigen, foo_kdl);
00614 ROS_ASSERT(foo_eigen == foo_kdl);
00615
00616 foo_eigen = joint_pos_eigen_[free_vars_start_][0](0);
00617 foo_kdl = joint_pos_[free_vars_start_][0](0);
00618 printf("eigen = %f, kdl = %f\n", foo_eigen, foo_kdl);
00619 ROS_ASSERT(foo_eigen==foo_kdl);
00620
00621 foo_eigen = collision_point_pos_eigen_[free_vars_start_][5](0);
00622 foo_kdl = collision_point_pos_[free_vars_start_][5](0);
00623 printf("eigen = %f, kdl = %f\n", foo_eigen, foo_kdl);
00624 ROS_ASSERT(foo_eigen==foo_kdl);
00625 }
00626
00627 void ChompOptimizer::perturbTrajectory()
00628 {
00629
00630 if (worst_collision_cost_state_ < 0)
00631 return;
00632 int mid_point = worst_collision_cost_state_;
00633 planning_group_->getRandomState(random_state_);
00634
00635
00636 random_state_ -= group_trajectory_.getTrajectoryPoint(mid_point).transpose();
00637
00638
00639 group_trajectory_.getJointVelocities(mid_point, joint_state_velocities_);
00640 joint_state_velocities_.normalize();
00641 random_state_ = (Eigen::MatrixXd::Identity(num_joints_, num_joints_) - joint_state_velocities_*joint_state_velocities_.transpose()) * random_state_;
00642
00643 int mp_free_vars_index = mid_point - free_vars_start_;
00644 for (int i=0; i<num_joints_; i++)
00645 {
00646 group_trajectory_.getFreeJointTrajectoryBlock(i) +=
00647 joint_costs_[i].getQuadraticCostInverse().col(mp_free_vars_index) * random_state_(i);
00648 }
00649 }
00650
00651 void ChompOptimizer::getRandomMomentum()
00652 {
00653 if (is_collision_free_)
00654 random_momentum_.setZero(num_vars_free_, num_joints_);
00655 else
00656 for (int i=0; i<num_joints_; ++i)
00657 {
00658 multivariate_gaussian_[i].sample(random_joint_momentum_);
00659 random_momentum_.col(i) = stochasticity_factor_ * random_joint_momentum_;
00660 }
00661 }
00662
00663 void ChompOptimizer::updateMomentum()
00664 {
00665
00666 double eps = parameters_->getHmcDiscretization();
00667 if (iteration_ > 0)
00668 momentum_ = (momentum_ + eps*final_increments_);
00669 else
00670 momentum_ = random_momentum_;
00671
00672 }
00673
00674 void ChompOptimizer::updatePositionFromMomentum()
00675 {
00676 double eps = parameters_->getHmcDiscretization();
00677 group_trajectory_.getFreeTrajectoryBlock() += eps * momentum_;
00678 }
00679
00680 void ChompOptimizer::animatePath()
00681 {
00682 for (int i=free_vars_start_; i<=free_vars_end_; i++)
00683 {
00684 visualizeState(i);
00685
00686 ros::WallDuration(.05).sleep();
00687 }
00688 }
00689
00690 void ChompOptimizer::animateEndeffector()
00691 {
00692 visualization_msgs::Marker msg;
00693 msg.points.resize(num_vars_free_);
00694
00695 int sn = animate_endeffector_segment_number_;
00696 for (int i=0; i<num_vars_free_; ++i)
00697 {
00698 int j = i+free_vars_start_;
00699 msg.points[i].x = segment_frames_[j][sn].p.x();
00700 msg.points[i].y = segment_frames_[j][sn].p.y();
00701 msg.points[i].z = segment_frames_[j][sn].p.z();
00702 }
00703 msg.header.frame_id = robot_model_->getReferenceFrame();
00704 msg.header.stamp = ros::Time();
00705 msg.ns = "chomp_endeffector";
00706 msg.id = 0;
00707 msg.type = visualization_msgs::Marker::SPHERE_LIST;
00708 msg.action = visualization_msgs::Marker::ADD;
00709 double scale = 0.05;
00710 msg.scale.x = scale;
00711 msg.scale.y = scale;
00712 msg.scale.z = scale;
00713 msg.color.a = 0.6;
00714 msg.color.r = 0.5;
00715 msg.color.g = 1.0;
00716 msg.color.b = 0.3;
00717 vis_marker_pub_.publish(msg);
00718 ros::WallDuration(0.1).sleep();
00719 }
00720
00721 void ChompOptimizer::visualizeState(int index)
00722 {
00723 visualization_msgs::MarkerArray msg;
00724 msg.markers.resize(num_collision_points_ + num_joints_);
00725 int num_arrows = 0;
00726 double potential_threshold = 1e-10;
00727 for (int i=0; i<num_collision_points_; i++)
00728 {
00729 msg.markers[i].header.frame_id = robot_model_->getReferenceFrame();
00730 msg.markers[i].header.stamp = ros::Time();
00731 msg.markers[i].ns = "chomp_collisions";
00732 msg.markers[i].id = i;
00733 msg.markers[i].type = visualization_msgs::Marker::SPHERE;
00734 msg.markers[i].action = visualization_msgs::Marker::ADD;
00735 msg.markers[i].pose.position.x = collision_point_pos_[index][i].x();
00736 msg.markers[i].pose.position.y = collision_point_pos_[index][i].y();
00737 msg.markers[i].pose.position.z = collision_point_pos_[index][i].z();
00738 msg.markers[i].pose.orientation.x = 0.0;
00739 msg.markers[i].pose.orientation.y = 0.0;
00740 msg.markers[i].pose.orientation.z = 0.0;
00741 msg.markers[i].pose.orientation.w = 1.0;
00742 double scale = planning_group_->collision_points_[i].getRadius()*2;
00743 msg.markers[i].scale.x = scale;
00744 msg.markers[i].scale.y = scale;
00745 msg.markers[i].scale.z = scale;
00746 msg.markers[i].color.a = 0.6;
00747 msg.markers[i].color.r = 0.5;
00748 msg.markers[i].color.g = 1.0;
00749 msg.markers[i].color.b = 0.3;
00750 if (collision_point_potential_[index][i] > potential_threshold)
00751 num_arrows++;
00752 }
00753 for (int j=0; j<num_joints_; ++j)
00754 {
00755 int i=num_collision_points_+j;
00756 int joint_index = planning_group_->chomp_joints_[j].kdl_joint_index_;
00757 msg.markers[i].header.frame_id = robot_model_->getReferenceFrame();
00758 msg.markers[i].header.stamp = ros::Time();
00759 msg.markers[i].ns = "chomp_collisions";
00760 msg.markers[i].id = i;
00761 msg.markers[i].type = visualization_msgs::Marker::ARROW;
00762 msg.markers[i].action = visualization_msgs::Marker::ADD;
00763 msg.markers[i].points.resize(2);
00764 double scale=0.2;
00765 double sx = joint_axis_[index][joint_index].x()*scale;
00766 double sy = joint_axis_[index][joint_index].y()*scale;
00767 double sz = joint_axis_[index][joint_index].z()*scale;
00768 msg.markers[i].points[0].x = joint_pos_[index][joint_index].x() - sx;
00769 msg.markers[i].points[0].y = joint_pos_[index][joint_index].y() - sy;
00770 msg.markers[i].points[0].z = joint_pos_[index][joint_index].z() - sz;
00771 msg.markers[i].points[1].x = joint_pos_[index][joint_index].x() + sx;
00772 msg.markers[i].points[1].y = joint_pos_[index][joint_index].y() + sy;
00773 msg.markers[i].points[1].z = joint_pos_[index][joint_index].z() + sz;
00774 msg.markers[i].scale.x = 0.03;
00775 msg.markers[i].scale.y = 0.06;
00776 msg.markers[i].color.a = 1.0;
00777 msg.markers[i].color.r = 1.0;
00778 msg.markers[i].color.g = 0.5;
00779 msg.markers[i].color.b = 0.5;
00780 }
00781 vis_marker_array_pub_.publish(msg);
00782
00783
00784 msg.markers.resize(0);
00785 msg.markers.resize(num_collision_points_);
00786 for (int i=0; i<num_collision_points_; i++)
00787 {
00788 msg.markers[i].header.frame_id = robot_model_->getReferenceFrame();
00789 msg.markers[i].header.stamp = ros::Time();
00790 msg.markers[i].ns = "chomp_arrows";
00791 msg.markers[i].id = i;
00792 msg.markers[i].type = visualization_msgs::Marker::ARROW;
00793 msg.markers[i].action = visualization_msgs::Marker::ADD;
00794 msg.markers[i].points.resize(2);
00795 msg.markers[i].points[0].x = collision_point_pos_[index][i].x();
00796 msg.markers[i].points[0].y = collision_point_pos_[index][i].y();
00797 msg.markers[i].points[0].z = collision_point_pos_[index][i].z();
00798 msg.markers[i].points[1] = msg.markers[i].points[0];
00799 double scale = planning_group_->collision_points_[i].getRadius()*3;
00800 if (collision_point_potential_[index][i] <= potential_threshold)
00801 scale = 0.0;
00802 msg.markers[i].points[1].x -= scale*collision_point_potential_gradient_[index][i].x();
00803 msg.markers[i].points[1].y -= scale*collision_point_potential_gradient_[index][i].y();
00804 msg.markers[i].points[1].z -= scale*collision_point_potential_gradient_[index][i].z();
00805 msg.markers[i].scale.x = 0.01;
00806 msg.markers[i].scale.y = 0.03;
00807 msg.markers[i].color.a = 1.0;
00808 msg.markers[i].color.r = 0.2;
00809 msg.markers[i].color.g = 0.2;
00810 msg.markers[i].color.b = 1.0;
00811 }
00812 vis_marker_array_pub_.publish(msg);
00813 }
00814
00815 }