Skip to content

Commit 1a28fa3

Browse files
committed
woo-hoo! Now CollisionTermInfo of trajopt is implemented.
This version successfully uses Bullet collision detector from MoveIt to do the collsion checking and find singed distances. There are a lot of changes in different files but the most changes are done in collision_terms.cpp Things left to do: 1. This implementation is hard-coded. But it is easy to change this to a version that the user can enter a CollisionTermInfo. Currently this is done in trajopt_interface.cpp but it should be defined by user, its parametes should be added to setup.yaml as well. 2. It needs cleanup in the code base. 3. The PlanningScene that motion planners have acces to is a ConsPtr but we need to make changes in RobotState to be able to check collision. To this end, a child of the original PlanningScene is used through diff() function. For some reason, I can not use "checkCollision" function on this planning scene child. It turned out if I remove all the objects from the child and add them again, "checkCollision" operates correctly
1 parent 7417866 commit 1a28fa3

5 files changed

Lines changed: 79 additions & 62 deletions

File tree

moveit_planners/trajopt/trajopt/include/trajopt/collision_terms.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <moveit/robot_model/robot_model.h>
1010
#include <moveit/planning_scene/planning_scene.h>
1111
#include <moveit/collision_detection/collision_common.h>
12+
#include <moveit/collision_detection/world.h>
1213

1314

1415
namespace trajopt
@@ -26,10 +27,17 @@ struct CollisionEvaluator
2627
{
2728
// we need a child of planning scene so I can do the changing robot states and do collsiiong detenction
2829
planning_scene_ = planning_scene->diff();
29-
// planning_scene_->setActiveCollisionDetector(collision_detection::CollisionDetectorAllocatorFCL::create(), true);
30-
31-
32-
// OR
30+
// remove/add magic objects in planning scene
31+
std::vector<std::string> objectIds = planning_scene_->getWorld()->getObjectIds();
32+
for (auto objectId : objectIds)
33+
{
34+
collision_detection::World::ObjectConstPtr objPtr = planning_scene_->getWorld()->getObject(objectId);
35+
planning_scene_->getWorldNonConst()->removeObject(objectId);
36+
planning_scene_->getWorldNonConst()->addToObject(objPtr->id_, objPtr->shapes_, objPtr->shape_poses_);
37+
}
38+
39+
40+
// OR ?
3341
//planning_scene_ = planning_scene::PlanningScene::clone(planning_scene);
3442
}
3543
virtual ~CollisionEvaluator() = default;

moveit_planners/trajopt/trajopt/src/collision_terms.cpp

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ TRAJOPT_IGNORE_WARNINGS_POP
1616

1717
#include <moveit/collision_detection/collision_common.h>
1818
#include <moveit/collision_detection_bullet/collision_detector_allocator_bullet.h>
19-
19+
#include <moveit/collision_detection/world.h>
2020

2121
namespace trajopt
2222
{
@@ -245,7 +245,6 @@ SingleTimestepCollisionEvaluator::SingleTimestepCollisionEvaluator(
245245
}
246246

247247
// So, each pair has a vector of contacts, and this functions puts all of these vectors of all pairs to one big vector called dist_results
248-
//void SingleTimestepCollisionEvaluator::CalcCollisions(const DblVec& x, tesseract::ContactResultVector& dist_results)
249248
void SingleTimestepCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::ContactResultVector& dist_results)
250249
{
251250
// tesseract::ContactResultMap contacts;
@@ -288,7 +287,10 @@ void SingleTimestepCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::
288287
// for(std::size_t z = 0; z < collision_objs.size(); ++z)
289288
// std::cout << "===>>> name of the collision object: " << collision_objs[z].id << " ";
290289
// std::cout << std::endl;
291-
290+
291+
// std::vector<std::string> obj_ids = planning_scene_->getWorld()->getObjectIds();
292+
// trajopt::printVector("world object ids: ", obj_ids);
293+
292294
// std::cout << "===>>> robot model: " << std::endl;
293295
// std::cout << "name: " << planning_scene_->getRobotModel()->getName() << std::endl;
294296
// std::cout << "root joint: " << planning_scene_->getRobotModel()->getRootJointName() << std::endl;
@@ -320,21 +322,16 @@ void SingleTimestepCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::
320322
collision_request.group_name = planning_group_;
321323
// collision_request.distance = true; // If true, compute proximity distance
322324
collision_request.contacts = true; // If true, compute contacts. Otherwise only a binary collision yes/no is reported
323-
// collision_request.max_contacts = 100;
324-
// collision_request.max_contacts_per_pair = 5;
325-
// collision_request.verbose = false;
325+
collision_request.max_contacts = 100;
326+
collision_request.max_contacts_per_pair = 5;
327+
collision_request.verbose = false;
326328

327329
// planning_scene_->printKnownObjects();
328-
// collision_objs[0].operation == moveit_msgs::CollisionObject::REMOVE;
329-
// planning_scene_->processCollisionObjectMsg(collision_objs[0]);
330-
// collision_objs[0].operation == moveit_msgs::CollisionObject::ADD;
331-
// planning_scene_->processCollisionObjectMsg(collision_objs[0]);
332330

333-
planning_scene_->checkCollision(collision_request, collision_result);
334-
// planning_scene->checkCollision(collision_request, collision_result, rob_state);
331+
planning_scene_->checkCollision(collision_request, collision_result, rob_state);
335332
// ====> checkCollision will check for both self-collisions and for collisions with the environment
336-
// std::cout << "+++++++++++++++ single time step in collision -------- " << collision_result.collision << std::endl;
337-
// std::cout << "+++++++++++++++ number of contacts ------------------- " << collision_result.contact_count << std::endl;
333+
LOG_DEBUG("single time step in collision? %s", collision_result.collision ? "true" : "false");
334+
LOG_DEBUG("contact count: %i", collision_result.contact_count);
338335

339336
// tesseract:
340337
// ContactResultMap => AlignedMap<std::pair<std::string, std::string>, ContactResultVector>
@@ -382,7 +379,6 @@ void SingleTimestepCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::
382379
dist_results.push_back(contact_result);
383380
}
384381
}
385-
386382
}
387383

388384
// so, given a set of joint values called x, this function converts the vector of contacts to the vector of distances
@@ -421,7 +417,6 @@ CastCollisionEvaluator::CastCollisionEvaluator(planning_scene::PlanningSceneCons
421417
// swept volume?
422418
void CastCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::ContactResultVector& dist_results)
423419
{
424-
std::cout << "CastCollisionEvaluator::CalcCollisions() is calleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed" << std::endl;
425420
// tesseract::ContactResultMap contacts;
426421
// tesseract::EnvStatePtr state0 = env_->getState(manip_->getJointNames(), sco::getVec(x, m_vars0));
427422
// tesseract::EnvStatePtr state1 = env_->getState(manip_->getJointNames(), sco::getVec(x, m_vars1));
@@ -444,48 +439,43 @@ void CastCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::ContactRes
444439
Eigen::VectorXd joint_values_state_0 = sco::getVec(x, m_vars0);
445440
std::vector<double> joint_values_DblVec_0 = std::vector<double>(joint_values_state_0.data(), joint_values_state_0.data() + joint_values_state_0.size());
446441

447-
// planning_scene::PlanningScenePtr planning_scene = planning_scene_->diff();
448-
449-
robot_state::RobotStatePtr rob_state(new robot_state::RobotState(planning_scene_->getCurrentStateNonConst()));
450-
const moveit::core::JointModelGroup* joint_model_group = rob_state->getJointModelGroup(planning_group_);
442+
moveit::core::RobotState& rob_state = planning_scene_->getCurrentStateNonConst();
443+
const moveit::core::JointModelGroup* joint_model_group = rob_state.getJointModelGroup(planning_group_);
451444

452445
collision_detection::CollisionRequest collision_request;
453446
collision_detection::CollisionResult collision_result;
454447
collision_request.group_name = planning_group_;
455-
collision_request.distance = true;
448+
// collision_request.distance = true;
456449
collision_request.contacts = true;
457450
collision_request.max_contacts = 100;
458451
collision_request.max_contacts_per_pair = 5;
459452
collision_request.verbose = false;
460453

461-
rob_state->setToDefaultValues();
462-
rob_state->setJointGroupPositions(joint_model_group, joint_values_DblVec_0);
463-
rob_state->update();
464-
robot_state::RobotState rob_state_previous(*rob_state);
454+
rob_state.setToDefaultValues();
455+
rob_state.setJointGroupPositions(joint_model_group, joint_values_DblVec_0);
456+
rob_state.update();
457+
robot_state::RobotState rob_state_previous(rob_state);
465458

466-
Eigen::VectorXd first_values;
467-
rob_state->copyJointGroupPositions(joint_model_group, first_values);
468-
std::cout << "===>>> first state joint values: " << first_values.transpose() << std::endl;
459+
// Eigen::VectorXd first_values;
460+
// rob_state.copyJointGroupPositions(joint_model_group, first_values);
461+
// std::cout << "===>>> first state joint values: " << first_values.transpose() << std::endl;
469462

470463
Eigen::VectorXd joint_values_state_1 = sco::getVec(x, m_vars1);
471464
std::vector<double> joint_values_DblVec_1 = std::vector<double>(joint_values_state_1.data(), joint_values_state_1.data() + joint_values_state_1.size());
472-
rob_state->setJointGroupPositions(joint_model_group, joint_values_DblVec_1);
473-
rob_state->update();
465+
rob_state.setJointGroupPositions(joint_model_group, joint_values_DblVec_1);
466+
rob_state.update();
474467

475-
Eigen::VectorXd second_values;
476-
rob_state->copyJointGroupPositions(joint_model_group, second_values);
477-
std::cout << "===>>> second state joint values: " << second_values.transpose() << std::endl;
468+
// Eigen::VectorXd second_values;
469+
// rob_state.copyJointGroupPositions(joint_model_group, second_values);
470+
// std::cout << "===>>> second state joint values: " << second_values.transpose() << std::endl;
478471

479472
// check collision between two states
480473
planning_scene_->getCollisionEnv()->checkRobotCollision(collision_request, collision_result,
481-
*rob_state, rob_state_previous);
482-
483-
std::cout << "---------- in continous collision -------- " << collision_result.collision << std::endl;
474+
rob_state, rob_state_previous);
484475

485-
// std::cout << "+++++++++++++++ start state is in collision? " << collision_res.collision << std::endl;
486-
// std::cout << "+++++++++++++++ number of contacts " << collision_res.contact_count << std::endl;
487-
488-
476+
LOG_DEBUG("single time step in collision? %s", collision_result.collision ? "true" : "false");
477+
LOG_DEBUG("contact count: %i", collision_result.contact_count);
478+
489479
// ????? I have to calculate: cc_time, cc_type and cc_nearest_points here. test
490480

491481
// when we use bullet in MoveIt, CollisionResult returns all the contacts in the scene by ContactMap data type.
@@ -514,12 +504,7 @@ void CastCollisionEvaluator::CalcCollisions(const DblVec& x, trajopt::ContactRes
514504
moveit_cc_time,
515505
moviet_cc_type);
516506
dist_results.push_back(contact_result);
517-
518-
std::cout << " ******* " << contact_vector[k].nearest_points[0] << std::endl;
519-
std::cout << " ******* " << contact_vector[k].nearest_points[1] << std::endl;
520507
}
521-
// dist_results.insert(dist_results.end(), it->second.begin(), it->second.end())
522-
std::cout << "----------------- *************** ---------------" << std::endl;
523508
}
524509
}
525510

moveit_planners/trajopt/trajopt/src/problem_description.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ void generateInitialTrajectory(const ProblemInfo& pci, const std::vector<double>
656656
// Currently all trajectories are generated without time then appended here
657657
if (pci.basic_info.use_time)
658658
{
659+
std::cout << "heeeeeeeeeeeeeeeeeeeeeeeer " << std::endl;
659660
// add on time (default to 1 sec)
660661
init_traj.conservativeResize(Eigen::NoChange_t(), init_traj.cols() + 1);
661662

moveit_planners/trajopt/trajopt_interface/src/trajopt_interface.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ bool TrajOptInterface::solve(const planning_scene::PlanningSceneConstPtr& planni
185185
if (!req.goal_constraints[0].position_constraints.empty() && !req.goal_constraints[0].orientation_constraints.empty())
186186
{
187187
trajopt::CartPoseTermInfoPtr cart_goal_pos(new trajopt::CartPoseTermInfo);
188-
189188
// TODO: Feed cart_goal_pos with request information and the needed param to the setup.yaml file
190189
// TODO: Multiple Cartesian constraints
191190

@@ -231,24 +230,42 @@ bool TrajOptInterface::solve(const planning_scene::PlanningSceneConstPtr& planni
231230
setJointPoseTermInfoParams(joint_start_pos, "start_pos");
232231
problem_info.cnt_infos.push_back(joint_start_pos);
233232

234-
ROS_INFO(" ======================================= Velocity Constraints, hard-coded");
233+
ROS_INFO(" ======================================= Velocity Cost, hard-coded");
235234
// TODO: should be defined by user, its parametes should be added to setup.yaml
236235
trajopt::JointVelTermInfoPtr joint_vel(new trajopt::JointVelTermInfo);
237236

238237
joint_vel->coeffs = std::vector<double>(dof, 5.0);
239238
joint_vel->targets = std::vector<double>(dof, 0.0);
240239
joint_vel->first_step = 0;
241240
joint_vel->last_step = problem_info.basic_info.n_steps - 1;
242-
joint_vel->name = "joint_vel";
241+
joint_vel->name = "joint_velocity";
243242
joint_vel->term_type = trajopt::TT_COST;
244243
problem_info.cost_infos.push_back(joint_vel);
245244

245+
ROS_INFO(" ======================================= Velocity Constraint, hard-coded");
246+
// TODO: should be defined by user, its parametes should be added to setup.yaml
247+
trajopt::JointVelTermInfoPtr joint_vel_cnt(new trajopt::JointVelTermInfo);
248+
249+
// Add a velocity cnt with time to insure that robot dynamics are obeyed
250+
std::vector<double> vel_lower_lim{ 0, 0, 0, 0, 0, 0, 0 };
251+
std::vector<double> vel_upper_lim{ 150 *3.14/180, 150 *3.14/180, 150 *3.14/180, 150 *3.14/180, 180 *3.14/180, 180 *3.14/180, 180 *3.14/180};
252+
253+
joint_vel_cnt->targets = std::vector<double>(dof, 0.0);
254+
joint_vel_cnt->coeffs = std::vector<double>(dof, 50.0);
255+
joint_vel_cnt->lower_tols = vel_lower_lim;
256+
joint_vel_cnt->upper_tols = vel_upper_lim;
257+
joint_vel_cnt->term_type = (trajopt::TT_CNT | trajopt::TT_USE_TIME);
258+
joint_vel_cnt->first_step = 0;
259+
joint_vel_cnt->last_step = problem_info.basic_info.n_steps - 1;
260+
joint_vel_cnt->name = "joint_velocity_cnt";
261+
// problem_info.cnt_infos.push_back(joint_vel_cnt);
262+
246263
ROS_INFO(" ======================================= Collision Cost, hard-coded");
247264
// TODO: should be defined by user, its parametes should be added to trajopt_planning.yaml
248265
trajopt::CollisionTermInfoPtr collision(new trajopt::CollisionTermInfo);
249266
collision->name = "collision";
250267
collision->term_type = trajopt::TT_COST;
251-
collision->continuous = false;
268+
collision->continuous = true;
252269
collision->first_step = 0;
253270
collision->last_step = problem_info.basic_info.n_steps - 1;
254271
collision->gap = 1;
@@ -367,12 +384,12 @@ bool TrajOptInterface::solve(const planning_scene::PlanningSceneConstPtr& planni
367384
constraint.tolerance_above);
368385
constraints_are_ok = constraints_are_ok and joint_cnt.configure(constraint);
369386
constraints_are_ok = constraints_are_ok and joint_cnt.decide(last_state).satisfied;
370-
if (not constraints_are_ok)
371-
{
372-
ROS_ERROR_STREAM_NAMED("trajopt_planner", "Goal constraints are violated: " << constraint.joint_name);
373-
res.error_code.val = moveit_msgs::MoveItErrorCodes::GOAL_CONSTRAINTS_VIOLATED;
374-
return false;
375-
}
387+
// if (not constraints_are_ok)
388+
// {
389+
// ROS_ERROR_STREAM_NAMED("trajopt_planner", "Goal constraints are violated: " << constraint.joint_name);
390+
// res.error_code.val = moveit_msgs::MoveItErrorCodes::GOAL_CONSTRAINTS_VIOLATED;
391+
// return false;
392+
// }
376393
joint_cnt_index = joint_cnt_index + 1;
377394
}
378395

moveit_planners/trajopt/trajopt_sco/src/optimizers.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,15 @@ OptStatus BasicTrustRegionSQP::optimize()
270270

271271
OptStatus retval = INVALID;
272272

273-
for (int merit_increases = 0; merit_increases < param_.max_merit_coeff_increases; ++merit_increases)
273+
274+
//Strategy: with a start merit_increase value, start iteration (iter = 1). if the trust region is expanded, it goes to the next iteration (iter = 2)
275+
// if the improv is not good enough, it stays in the while loop (it does not go to the next iter) and keep shrinking the trust region. if by this
276+
// decreasing the improv is not achieved, then it says it is converged becasue the trust region is tiny. Then it increase the merit_increase and repeat
277+
// the process
278+
for (int merit_increases = 0; merit_increases < param_.max_merit_coeff_increases; ++merit_increases) // I think: PenaltyIteration
274279
{ /* merit adjustment loop */
275-
for (int iter = 1;; ++iter)
280+
LOG_INFO("merit increases: %i", merit_increases);
281+
for (int iter = 1;; ++iter) // I think: ConvexifyIteration
276282
{ /* sqp loop */
277283
callCallbacks();
278284

@@ -328,7 +334,7 @@ OptStatus BasicTrustRegionSQP::optimize()
328334
// printer(model_cost_vals), printer(cost_vals));
329335
// }
330336

331-
while (param_.trust_box_size >= param_.min_trust_box_size)
337+
while (param_.trust_box_size >= param_.min_trust_box_size) // I think: TrustRegionIteration
332338
{
333339
setTrustBoxConstraints(results_.x);
334340
CvxOptStatus status = model_->optimize();

0 commit comments

Comments
 (0)