@@ -37,13 +37,50 @@ TESSERACT_COMMON_IGNORE_WARNINGS_POP
37
37
38
38
namespace tesseract_planning
39
39
{
40
- /* *
41
- * @brief Checks if a waypoint is in collision
42
- * @param waypoint Must be a waypoint for which getJointPosition will return a position
43
- * @param input Process Input associated with waypoint. Needed for kinematics, etc.
44
- * @return True if in collision
45
- */
46
- bool WaypointInCollision (const Waypoint& waypoint, const ProcessInput& input)
40
+ bool StateInCollision (const Eigen::Ref<const Eigen::VectorXd>& start_pos,
41
+ const ProcessInput& input,
42
+ const FixStateCollisionProfile& profile)
43
+ {
44
+ using namespace tesseract_collision ;
45
+ using namespace tesseract_environment ;
46
+
47
+ auto env = input.tesseract ->getEnvironment ();
48
+ auto kin = input.tesseract ->getManipulatorManager ()->getFwdKinematicSolver (input.manip_info .manipulator );
49
+
50
+ std::vector<ContactResultMap> collisions;
51
+ tesseract_environment::StateSolver::Ptr state_solver = env->getStateSolver ();
52
+ DiscreteContactManager::Ptr manager = env->getDiscreteContactManager ();
53
+ AdjacencyMap::Ptr adjacency_map = std::make_shared<tesseract_environment::AdjacencyMap>(
54
+ env->getSceneGraph (), kin->getActiveLinkNames (), env->getCurrentState ()->link_transforms );
55
+
56
+ manager->setActiveCollisionObjects (adjacency_map->getActiveLinkNames ());
57
+ manager->setContactDistanceThreshold (profile.safety_margin );
58
+ collisions.clear ();
59
+
60
+ tesseract_common::TrajArray traj (1 , start_pos.size ());
61
+ traj.row (0 ) = start_pos.transpose ();
62
+
63
+ // This never returns any collisions
64
+ if (!checkTrajectory (collisions, *manager, *state_solver, kin->getJointNames (), traj))
65
+ {
66
+ CONSOLE_BRIDGE_logDebug (" No collisions found" );
67
+ return false ;
68
+ }
69
+ else
70
+ {
71
+ CONSOLE_BRIDGE_logDebug (" Waypoint is not contact free!" );
72
+ for (std::size_t i = 0 ; i < collisions.size (); i++)
73
+ for (const auto & contact_vec : collisions[i])
74
+ for (const auto & contact : contact_vec.second )
75
+ CONSOLE_BRIDGE_logDebug ((" timestep: " + std::to_string (i) + " Links: " + contact.link_names [0 ] + " , " +
76
+ contact.link_names [1 ] + " Dist: " + std::to_string (contact.distance ))
77
+ .c_str ());
78
+ }
79
+
80
+ return true ;
81
+ }
82
+
83
+ bool WaypointInCollision (const Waypoint& waypoint, const ProcessInput& input, const FixStateCollisionProfile& profile)
47
84
{
48
85
// Get position associated with waypoint
49
86
Eigen::VectorXd start_pos;
@@ -56,56 +93,9 @@ bool WaypointInCollision(const Waypoint& waypoint, const ProcessInput& input)
56
93
CONSOLE_BRIDGE_logError (" WaypointInCollision error: %s" , e.what ());
57
94
return false ;
58
95
}
59
-
60
- // Check if there are collisions
61
- {
62
- using namespace tesseract_collision ;
63
- using namespace tesseract_environment ;
64
-
65
- auto env = input.tesseract ->getEnvironment ();
66
- auto kin = input.tesseract ->getManipulatorManager ()->getFwdKinematicSolver (input.manip_info .manipulator );
67
-
68
- std::vector<ContactResultMap> collisions;
69
- tesseract_environment::StateSolver::Ptr state_solver = env->getStateSolver ();
70
- DiscreteContactManager::Ptr manager = env->getDiscreteContactManager ();
71
- AdjacencyMap::Ptr adjacency_map = std::make_shared<tesseract_environment::AdjacencyMap>(
72
- env->getSceneGraph (), kin->getActiveLinkNames (), env->getCurrentState ()->link_transforms );
73
-
74
- manager->setActiveCollisionObjects (adjacency_map->getActiveLinkNames ());
75
- manager->setContactDistanceThreshold (0 );
76
- collisions.clear ();
77
-
78
- tesseract_common::TrajArray traj (1 , start_pos.size ());
79
- traj.row (0 ) = start_pos.transpose ();
80
-
81
- // This never returns any collisions
82
- if (!checkTrajectory (collisions, *manager, *state_solver, kin->getJointNames (), traj))
83
- {
84
- CONSOLE_BRIDGE_logDebug (" No collisions found" );
85
- return false ;
86
- }
87
- else
88
- {
89
- CONSOLE_BRIDGE_logDebug (" Waypoint is not contact free!" );
90
- for (std::size_t i = 0 ; i < collisions.size (); i++)
91
- for (const auto & contact_vec : collisions[i])
92
- for (const auto & contact : contact_vec.second )
93
- CONSOLE_BRIDGE_logDebug ((" timestep: " + std::to_string (i) + " Links: " + contact.link_names [0 ] + " , " +
94
- contact.link_names [1 ] + " Dist: " + std::to_string (contact.distance ))
95
- .c_str ());
96
- }
97
- }
98
-
99
- return true ;
96
+ return StateInCollision (start_pos, input, profile);
100
97
}
101
98
102
- /* *
103
- * @brief Takes a waypoint and uses a small trajopt problem to push it out of collision if necessary
104
- * @param waypoint Must be a waypoint for which getJointPosition will return a position
105
- * @param input Process Input associated with waypoint. Needed for kinematics, etc.
106
- * @param profile Profile containing needed params
107
- * @return True if successful
108
- */
109
99
bool MoveWaypointFromCollisionTrajopt (Waypoint& waypoint,
110
100
const ProcessInput& input,
111
101
const FixStateCollisionProfile& profile)
@@ -199,6 +189,70 @@ bool MoveWaypointFromCollisionTrajopt(Waypoint& waypoint,
199
189
return setJointPosition (waypoint, results);
200
190
}
201
191
192
+ bool MoveWaypointFromCollisionRandomSampler (Waypoint& waypoint,
193
+ const ProcessInput& input,
194
+ const FixStateCollisionProfile& profile)
195
+ {
196
+ // Get position associated with waypoint
197
+ Eigen::VectorXd start_pos;
198
+ try
199
+ {
200
+ start_pos = getJointPosition (waypoint);
201
+ }
202
+ catch (std::runtime_error& e)
203
+ {
204
+ CONSOLE_BRIDGE_logError (" MoveWaypointFromCollision error: %s" , e.what ());
205
+ return false ;
206
+ }
207
+
208
+ const auto kin = input.tesseract ->getManipulatorManager ()->getFwdKinematicSolver (input.manip_info .manipulator );
209
+ Eigen::MatrixXd limits = kin->getLimits ().joint_limits ;
210
+ Eigen::VectorXd range = limits.col (1 ).array () - limits.col (0 ).array ();
211
+ Eigen::VectorXd pos_sampling_limits = range * profile.jiggle_factor ;
212
+ Eigen::VectorXd neg_sampline_limits = range * -profile.jiggle_factor ;
213
+
214
+ assert (start_pos.size () == range.size ());
215
+ for (int i = 0 ; i < profile.sampling_attempts ; i++)
216
+ {
217
+ Eigen::VectorXd start_sampled_pos =
218
+ start_pos + Eigen::VectorXd::Random (start_pos.size ()).cwiseProduct (range) * profile.jiggle_factor ;
219
+
220
+ // Make sure it doesn't violate joint limits
221
+ Eigen::VectorXd sampled_pos = start_sampled_pos;
222
+ sampled_pos = sampled_pos.cwiseMax (limits.col (0 ));
223
+ sampled_pos = sampled_pos.cwiseMin (limits.col (1 ));
224
+
225
+ if (!StateInCollision (sampled_pos, input, profile))
226
+ {
227
+ return setJointPosition (waypoint, sampled_pos);
228
+ }
229
+ }
230
+
231
+ return false ;
232
+ }
233
+
234
+ bool ApplyCorrectionWorkflow (Waypoint& waypoint, const ProcessInput& input, const FixStateCollisionProfile& profile)
235
+ {
236
+ for (const auto & method : profile.correction_workflow )
237
+ {
238
+ switch (method)
239
+ {
240
+ case FixStateCollisionProfile::CorrectionMethod::NONE:
241
+ return false ; // No correction and in collision, so return false
242
+ case FixStateCollisionProfile::CorrectionMethod::TRAJOPT:
243
+ if (MoveWaypointFromCollisionTrajopt (waypoint, input, profile))
244
+ return true ;
245
+ break ;
246
+ case FixStateCollisionProfile::CorrectionMethod::RANDOM_SAMPLER:
247
+ if (MoveWaypointFromCollisionRandomSampler (waypoint, input, profile))
248
+ return true ;
249
+ break ;
250
+ }
251
+ }
252
+ // If all methods have tried without returning, then correction failed
253
+ return false ;
254
+ }
255
+
202
256
FixStateCollisionProcessGenerator::FixStateCollisionProcessGenerator (std::string name) : name_(std::move(name))
203
257
{
204
258
// Register default profile
@@ -268,10 +322,10 @@ int FixStateCollisionProcessGenerator::conditionalProcess(ProcessInput input) co
268
322
if (instr_const_ptr)
269
323
{
270
324
PlanInstruction* mutable_instruction = const_cast <PlanInstruction*>(instr_const_ptr);
271
- if (WaypointInCollision (mutable_instruction->getWaypoint (), input))
325
+ if (WaypointInCollision (mutable_instruction->getWaypoint (), input, *cur_composite_profile ))
272
326
{
273
327
CONSOLE_BRIDGE_logInform (" FixStateCollisionProcessGenerator is modifying the const input instructions" );
274
- if (!MoveWaypointFromCollisionTrajopt (mutable_instruction->getWaypoint (), input, *cur_composite_profile))
328
+ if (!ApplyCorrectionWorkflow (mutable_instruction->getWaypoint (), input, *cur_composite_profile))
275
329
return 0 ;
276
330
}
277
331
}
@@ -283,10 +337,10 @@ int FixStateCollisionProcessGenerator::conditionalProcess(ProcessInput input) co
283
337
if (instr_const_ptr)
284
338
{
285
339
PlanInstruction* mutable_instruction = const_cast <PlanInstruction*>(instr_const_ptr);
286
- if (WaypointInCollision (mutable_instruction->getWaypoint (), input))
340
+ if (WaypointInCollision (mutable_instruction->getWaypoint (), input, *cur_composite_profile ))
287
341
{
288
342
CONSOLE_BRIDGE_logInform (" FixStateCollisionProcessGenerator is modifying the const input instructions" );
289
- if (!MoveWaypointFromCollisionTrajopt (mutable_instruction->getWaypoint (), input, *cur_composite_profile))
343
+ if (!ApplyCorrectionWorkflow (mutable_instruction->getWaypoint (), input, *cur_composite_profile))
290
344
return 0 ;
291
345
}
292
346
}
@@ -304,7 +358,8 @@ int FixStateCollisionProcessGenerator::conditionalProcess(ProcessInput input) co
304
358
bool in_collision = false ;
305
359
for (const auto & instruction : flattened)
306
360
{
307
- in_collision |= WaypointInCollision (instruction.get ().cast_const <PlanInstruction>()->getWaypoint (), input);
361
+ in_collision |= WaypointInCollision (
362
+ instruction.get ().cast_const <PlanInstruction>()->getWaypoint (), input, *cur_composite_profile);
308
363
}
309
364
if (!in_collision)
310
365
break ;
@@ -315,7 +370,8 @@ int FixStateCollisionProcessGenerator::conditionalProcess(ProcessInput input) co
315
370
const Instruction* instr_const_ptr = &instruction.get ();
316
371
Instruction* mutable_instruction = const_cast <Instruction*>(instr_const_ptr);
317
372
PlanInstruction* plan = mutable_instruction->cast <PlanInstruction>();
318
- if (!MoveWaypointFromCollisionTrajopt (plan->getWaypoint (), input, *cur_composite_profile))
373
+
374
+ if (!ApplyCorrectionWorkflow (plan->getWaypoint (), input, *cur_composite_profile))
319
375
return 0 ;
320
376
}
321
377
}
0 commit comments