collision_check_thread.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2019, Los Alamos National Security, LLC
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *******************************************************************************/
33 
34 /* Title : collision_check_thread.cpp
35  * Project : moveit_jog_arm
36  * Created : 1/11/2019
37  * Author : Brian O'Neil, Andy Zelenak, Blake Anderson
38  */
39 
41 
42 static const std::string LOGNAME = "collision_check_thread";
43 static const double MIN_RECOMMENDED_COLLISION_RATE = 10;
44 
45 namespace moveit_jog_arm
46 {
47 // Constructor for the class that handles collision checking
49  const moveit_jog_arm::JogArmParameters& parameters,
50  const planning_scene_monitor::PlanningSceneMonitorPtr& planning_scene_monitor)
51  : parameters_(parameters), planning_scene_monitor_(planning_scene_monitor)
52 {
54  ROS_WARN_STREAM_THROTTLE_NAMED(5, LOGNAME, "Collision check rate is low, increase it in yaml file if CPU allows");
55 }
56 
58 {
60 }
61 
63 {
64  // Init collision request
65  collision_detection::CollisionRequest collision_request;
66  collision_request.group_name = parameters_.move_group_name;
67  collision_request.distance = true; // enable distance-based collision checking
68  collision_detection::CollisionResult collision_result;
69 
70  // Copy the planning scene's version of current state into new memory
71  moveit::core::RobotState current_state(getLockedPlanningSceneRO()->getCurrentState());
72 
73  const double self_velocity_scale_coefficient = -log(0.001) / parameters_.self_collision_proximity_threshold;
74  const double scene_velocity_scale_coefficient = -log(0.001) / parameters_.scene_collision_proximity_threshold;
76 
77  double self_collision_distance = 0;
78  double scene_collision_distance = 0;
79  bool collision_detected;
80 
81  // Scale robot velocity according to collision proximity and user-defined thresholds.
82  // I scaled exponentially (cubic power) so velocity drops off quickly after the threshold.
83  // Proximity decreasing --> decelerate
84  double velocity_scale = 1;
85 
86  collision_detection::AllowedCollisionMatrix acm = getLockedPlanningSceneRO()->getAllowedCollisionMatrix();
88  // Spin while checking collisions
90  while (ros::ok() && !shared_variables.stop_requested)
91  {
92  if (!shared_variables.paused)
93  {
94  shared_variables.lock();
95  sensor_msgs::JointState jts = shared_variables.joints;
96  shared_variables.unlock();
97 
98  for (std::size_t i = 0; i < jts.position.size(); ++i)
99  current_state.setJointPositions(jts.name[i], &jts.position[i]);
100 
101  current_state.updateCollisionBodyTransforms();
102  collision_detected = false;
103 
104  // Do a thread-safe distance-based collision detection
105  { // Lock PlanningScene
106  auto scene_ro = getLockedPlanningSceneRO();
107 
108  collision_result.clear();
109  scene_ro->getCollisionWorld()->checkRobotCollision(collision_request, collision_result,
110  *scene_ro->getCollisionRobot(), current_state, acm);
111 
112  scene_collision_distance = collision_result.distance;
113  collision_detected |= collision_result.collision;
114 
115  collision_result.clear();
116  scene_ro->getCollisionRobotUnpadded()->checkSelfCollision(collision_request, collision_result, current_state,
117  acm);
118  } // Unlock PlanningScene
119 
120  self_collision_distance = collision_result.distance;
121  collision_detected |= collision_result.collision;
122 
123  velocity_scale = 1;
124  // If we're definitely in collision, stop immediately
125  if (collision_detected)
126  {
127  velocity_scale = 0;
128  }
129 
130  // If we are far from a collision, velocity_scale should be 1.
131  // If we are very close to a collision, velocity_scale should be ~zero.
132  // When scene_collision_proximity_threshold is breached, start decelerating exponentially.
133  if (scene_collision_distance < parameters_.scene_collision_proximity_threshold)
134  {
135  // velocity_scale = e ^ k * (collision_distance - threshold)
136  // k = - ln(0.001) / collision_proximity_threshold
137  // velocity_scale should equal one when collision_distance is at collision_proximity_threshold.
138  // velocity_scale should equal 0.001 when collision_distance is at zero.
139  velocity_scale =
140  std::min(velocity_scale, exp(scene_velocity_scale_coefficient *
141  (scene_collision_distance - parameters_.scene_collision_proximity_threshold)));
142  }
143 
144  if (self_collision_distance < parameters_.self_collision_proximity_threshold)
145  {
146  velocity_scale =
147  std::min(velocity_scale, exp(self_velocity_scale_coefficient *
148  (self_collision_distance - parameters_.self_collision_proximity_threshold)));
149  }
150 
151  shared_variables.lock();
152  shared_variables.collision_velocity_scale = velocity_scale;
153  shared_variables.unlock();
154  }
155 
156  collision_rate.sleep();
157  }
158 }
159 } // namespace moveit_jog_arm
void setJointPositions(const std::string &joint_name, const double *position)
void startMainLoop(moveit_jog_arm::JogArmShared &shared_variables)
std::atomic< bool > stop_requested
Definition: jog_arm_data.h:103
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
INLINE Rall1d< T, V, S > log(const Rall1d< T, V, S > &arg)
static const std::string LOGNAME
std::atomic< bool > paused
Definition: jog_arm_data.h:100
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void clear()
sensor_msgs::JointState joints
Definition: jog_arm_data.h:67
#define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args)
ROSCPP_DECL bool ok()
const moveit_jog_arm::JogArmParameters parameters_
CollisionCheckThread(const moveit_jog_arm::JogArmParameters &parameters, const planning_scene_monitor::PlanningSceneMonitorPtr &planning_scene_monitor)
Constructor.
bool sleep()
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
planning_scene_monitor::LockedPlanningSceneRO getLockedPlanningSceneRO() const
static const double MIN_RECOMMENDED_COLLISION_RATE


moveit_jog_arm
Author(s): Brian O'Neil, Andy Zelenak , Blake Anderson, Alexander Rössler
autogenerated on Fri Jun 5 2020 03:53:46