jog_interface_base.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 : jog_interface_base.cpp
35  * Project : moveit_jog_arm
36  * Created : 3/9/2017
37  * Author : Brian O'Neil, Andy Zelenak, Blake Anderson
38  */
39 
41 
42 static const std::string LOGNAME = "jog_interface_base";
43 
44 namespace moveit_jog_arm
45 {
47 {
48 }
49 
50 // Read ROS parameters, typically from YAML file
52 {
53  std::size_t error = 0;
54 
55  // Specified in the launch file. All other parameters will be read from this namespace.
56  std::string parameter_ns;
57  ros::param::get("~parameter_ns", parameter_ns);
58  if (parameter_ns.empty())
59  {
60  ROS_ERROR_STREAM_NAMED(LOGNAME, "A namespace must be specified in the launch file, like:");
61  ROS_ERROR_STREAM_NAMED(LOGNAME, "<param name=\"parameter_ns\" "
62  "type=\"string\" "
63  "value=\"left_jog_server\" />");
64  return false;
65  }
66 
67  error += !rosparam_shortcuts::get("", n, parameter_ns + "/publish_period", ros_parameters_.publish_period);
68  error +=
69  !rosparam_shortcuts::get("", n, parameter_ns + "/collision_check_rate", ros_parameters_.collision_check_rate);
70  error += !rosparam_shortcuts::get("", n, parameter_ns + "/num_outgoing_halt_msgs_to_publish",
72  error += !rosparam_shortcuts::get("", n, parameter_ns + "/scale/linear", ros_parameters_.linear_scale);
73  error += !rosparam_shortcuts::get("", n, parameter_ns + "/scale/rotational", ros_parameters_.rotational_scale);
74  error += !rosparam_shortcuts::get("", n, parameter_ns + "/scale/joint", ros_parameters_.joint_scale);
75  error +=
76  !rosparam_shortcuts::get("", n, parameter_ns + "/low_pass_filter_coeff", ros_parameters_.low_pass_filter_coeff);
77  error += !rosparam_shortcuts::get("", n, parameter_ns + "/joint_topic", ros_parameters_.joint_topic);
78  error += !rosparam_shortcuts::get("", n, parameter_ns + "/command_in_type", ros_parameters_.command_in_type);
79  error += !rosparam_shortcuts::get("", n, parameter_ns + "/cartesian_command_in_topic",
81  error +=
82  !rosparam_shortcuts::get("", n, parameter_ns + "/joint_command_in_topic", ros_parameters_.joint_command_in_topic);
83  error += !rosparam_shortcuts::get("", n, parameter_ns + "/robot_link_command_frame",
85  error += !rosparam_shortcuts::get("", n, parameter_ns + "/incoming_command_timeout",
87  error += !rosparam_shortcuts::get("", n, parameter_ns + "/lower_singularity_threshold",
89  error += !rosparam_shortcuts::get("", n, parameter_ns + "/hard_stop_singularity_threshold",
91  // parameter was removed, replaced with separate self- and scene-collision proximity thresholds; the logic handling
92  // the different possible sets of defined parameters is somewhat complicated at this point
93  // TODO(JStech): remove this deprecation warning in ROS Noetic; simplify error case handling
94  bool have_self_collision_proximity_threshold = rosparam_shortcuts::get(
95  "", n, parameter_ns + "/self_collision_proximity_threshold", ros_parameters_.self_collision_proximity_threshold);
96  bool have_scene_collision_proximity_threshold =
97  rosparam_shortcuts::get("", n, parameter_ns + "/scene_collision_proximity_threshold",
99  double collision_proximity_threshold;
100  if (n.hasParam(parameter_ns + "/collision_proximity_threshold") &&
101  rosparam_shortcuts::get("", n, parameter_ns + "/collision_proximity_threshold", collision_proximity_threshold))
102  {
103  ROS_WARN_NAMED(LOGNAME, "'collision_proximity_threshold' parameter is deprecated, and has been replaced by separate"
104  "'self_collision_proximity_threshold' and 'scene_collision_proximity_threshold' "
105  "parameters. Please update the jogging yaml file.");
106  if (!have_self_collision_proximity_threshold)
107  {
108  ros_parameters_.self_collision_proximity_threshold = collision_proximity_threshold;
109  have_self_collision_proximity_threshold = true;
110  }
111  if (!have_scene_collision_proximity_threshold)
112  {
113  ros_parameters_.scene_collision_proximity_threshold = collision_proximity_threshold;
114  have_scene_collision_proximity_threshold = true;
115  }
116  }
117  error += !have_self_collision_proximity_threshold;
118  error += !have_scene_collision_proximity_threshold;
119  error += !rosparam_shortcuts::get("", n, parameter_ns + "/move_group_name", ros_parameters_.move_group_name);
120  error += !rosparam_shortcuts::get("", n, parameter_ns + "/planning_frame", ros_parameters_.planning_frame);
121  error += !rosparam_shortcuts::get("", n, parameter_ns + "/use_gazebo", ros_parameters_.use_gazebo);
122  error += !rosparam_shortcuts::get("", n, parameter_ns + "/check_collisions", ros_parameters_.check_collisions);
123  error += !rosparam_shortcuts::get("", n, parameter_ns + "/joint_limit_margin", ros_parameters_.joint_limit_margin);
124  error += !rosparam_shortcuts::get("", n, parameter_ns + "/command_out_topic", ros_parameters_.command_out_topic);
125  error += !rosparam_shortcuts::get("", n, parameter_ns + "/command_out_type", ros_parameters_.command_out_type);
126  error += !rosparam_shortcuts::get("", n, parameter_ns + "/publish_joint_positions",
128  error += !rosparam_shortcuts::get("", n, parameter_ns + "/publish_joint_velocities",
130  error += !rosparam_shortcuts::get("", n, parameter_ns + "/publish_joint_accelerations",
132 
133  // This parameter name was changed recently.
134  // Try retrieving from the correct name. If it fails, then try the deprecated name.
135  // TODO(andyz): remove this deprecation warning in ROS Noetic
136  if (!rosparam_shortcuts::get("", n, parameter_ns + "/status_topic", ros_parameters_.status_topic))
137  {
138  ROS_WARN_NAMED(LOGNAME, "'status_topic' parameter is missing. Recently renamed from 'warning_topic'. Please update "
139  "the jogging yaml file.");
140  error += !rosparam_shortcuts::get("", n, parameter_ns + "/warning_topic", ros_parameters_.status_topic);
141  }
142 
143  rosparam_shortcuts::shutdownIfError(parameter_ns, error);
144 
145  // Input checking
147  {
148  ROS_WARN_NAMED(LOGNAME, "Parameter 'publish_period' should be "
149  "greater than zero. Check yaml file.");
150  return false;
151  }
153  {
155  "Parameter 'num_outgoing_halt_msgs_to_publish' should be greater than zero. Check yaml file.");
156  return false;
157  }
159  {
160  ROS_WARN_NAMED(LOGNAME, "Parameter 'hard_stop_singularity_threshold' "
161  "should be greater than 'lower_singularity_threshold.' "
162  "Check yaml file.");
163  return false;
164  }
166  {
167  ROS_WARN_NAMED(LOGNAME, "Parameters 'hard_stop_singularity_threshold' "
168  "and 'lower_singularity_threshold' should be "
169  "greater than zero. Check yaml file.");
170  return false;
171  }
173  {
174  ROS_WARN_NAMED(LOGNAME, "Parameter 'self_collision_proximity_threshold' should be "
175  "greater than zero. Check yaml file.");
176  return false;
177  }
179  {
180  ROS_WARN_NAMED(LOGNAME, "Parameter 'scene_collision_proximity_threshold' should be "
181  "greater than zero. Check yaml file.");
182  return false;
183  }
185  {
186  ROS_WARN_NAMED(LOGNAME, "Parameter 'self_collision_proximity_threshold' should probably be less "
187  "than or equal to 'scene_collision_proximity_threshold'. Check yaml file.");
188  }
190  {
191  ROS_WARN_NAMED(LOGNAME, "Parameter 'low_pass_filter_coeff' should be "
192  "greater than zero. Check yaml file.");
193  return false;
194  }
196  {
197  ROS_WARN_NAMED(LOGNAME, "Parameter 'joint_limit_margin' should be "
198  "greater than zero. Check yaml file.");
199  return false;
200  }
201  if (ros_parameters_.command_in_type != "unitless" && ros_parameters_.command_in_type != "speed_units")
202  {
203  ROS_WARN_NAMED(LOGNAME, "command_in_type should be 'unitless' or "
204  "'speed_units'. Check yaml file.");
205  return false;
206  }
207  if (ros_parameters_.command_out_type != "trajectory_msgs/JointTrajectory" &&
208  ros_parameters_.command_out_type != "std_msgs/Float64MultiArray")
209  {
210  ROS_WARN_NAMED(LOGNAME, "Parameter command_out_type should be "
211  "'trajectory_msgs/JointTrajectory' or "
212  "'std_msgs/Float64MultiArray'. Check yaml file.");
213  return false;
214  }
217  {
218  ROS_WARN_NAMED(LOGNAME, "At least one of publish_joint_positions / "
219  "publish_joint_velocities / "
220  "publish_joint_accelerations must be true. Check "
221  "yaml file.");
222  return false;
223  }
224  if ((ros_parameters_.command_out_type == "std_msgs/Float64MultiArray") && ros_parameters_.publish_joint_positions &&
226  {
227  ROS_WARN_NAMED(LOGNAME, "When publishing a std_msgs/Float64MultiArray, "
228  "you must select positions OR velocities.");
229  return false;
230  }
232  {
233  ROS_WARN_NAMED(LOGNAME, "Parameter 'collision_check_rate' should be "
234  "greater than zero. Check yaml file.");
235  return false;
236  }
237 
238  return true;
239 }
240 
241 // Listen to joint angles. Store them in a shared variable.
242 void JogInterfaceBase::jointsCB(const sensor_msgs::JointStateConstPtr& msg)
243 {
244  shared_variables_.lock();
245  shared_variables_.joints = *msg;
246  shared_variables_.unlock();
247 }
248 
249 bool JogInterfaceBase::changeDriftDimensions(moveit_msgs::ChangeDriftDimensions::Request& req,
250  moveit_msgs::ChangeDriftDimensions::Response& res)
251 {
252  // These are std::atomic's, they are threadsafe without a mutex lock
253  shared_variables_.drift_dimensions[0] = req.drift_x_translation;
254  shared_variables_.drift_dimensions[1] = req.drift_y_translation;
255  shared_variables_.drift_dimensions[2] = req.drift_z_translation;
256  shared_variables_.drift_dimensions[3] = req.drift_x_rotation;
257  shared_variables_.drift_dimensions[4] = req.drift_y_rotation;
258  shared_variables_.drift_dimensions[5] = req.drift_z_rotation;
259 
260  res.success = true;
261  return true;
262 }
263 
264 bool JogInterfaceBase::changeControlDimensions(moveit_msgs::ChangeControlDimensions::Request& req,
265  moveit_msgs::ChangeControlDimensions::Response& res)
266 {
267  shared_variables_.control_dimensions[0] = req.control_x_translation;
268  shared_variables_.control_dimensions[1] = req.control_y_translation;
269  shared_variables_.control_dimensions[2] = req.control_z_translation;
270  shared_variables_.control_dimensions[3] = req.control_x_rotation;
271  shared_variables_.control_dimensions[4] = req.control_y_rotation;
272  shared_variables_.control_dimensions[5] = req.control_z_rotation;
273 
274  res.success = true;
275  return true;
276 }
277 
278 // A separate thread for the heavy jogging calculations.
280 {
281  if (!jog_calcs_)
282  jog_calcs_.reset(new JogCalcs(ros_parameters_, planning_scene_monitor_->getRobotModelLoader()));
283 
284  jog_calc_thread_.reset(new std::thread([&]() { jog_calcs_->startMainLoop(shared_variables_); }));
285 
286  return true;
287 }
288 
290 {
291  if (jog_calc_thread_)
292  {
293  if (jog_calc_thread_->joinable())
294  jog_calc_thread_->join();
295 
296  jog_calc_thread_.reset();
297  }
298 
299  return true;
300 }
301 
302 // A separate thread for collision checking.
304 {
305  if (!collision_checker_)
307 
308  collision_check_thread_.reset(new std::thread([&]() { collision_checker_->startMainLoop(shared_variables_); }));
309 
310  return true;
311 }
312 
314 {
316  {
317  if (collision_check_thread_->joinable())
318  collision_check_thread_->join();
319 
320  collision_check_thread_.reset();
321  }
322 
323  return true;
324 }
325 } // namespace moveit_jog_arm
std::unique_ptr< CollisionCheckThread > collision_checker_
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
#define ROS_ERROR_STREAM_NAMED(name, args)
#define ROS_WARN_NAMED(name,...)
static const std::string LOGNAME
sensor_msgs::JointState joints
Definition: jog_arm_data.h:67
bool startCollisionCheckThread()
Start collision checking.
std::unique_ptr< std::thread > jog_calc_thread_
std::atomic_bool drift_dimensions[6]
Definition: jog_arm_data.h:93
std::unique_ptr< std::thread > collision_check_thread_
std::atomic_bool control_dimensions[6]
Definition: jog_arm_data.h:106
std::unique_ptr< JogCalcs > jog_calcs_
ROSCPP_DECL bool get(const std::string &key, std::string &s)
bool changeDriftDimensions(moveit_msgs::ChangeDriftDimensions::Request &req, moveit_msgs::ChangeDriftDimensions::Response &res)
bool stopCollisionCheckThread()
Stop collision checking.
bool stopJogCalcThread()
Stop the main calculation thread.
bool hasParam(const std::string &key) const
void shutdownIfError(const std::string &parent_name, std::size_t error_count)
bool changeControlDimensions(moveit_msgs::ChangeControlDimensions::Request &req, moveit_msgs::ChangeControlDimensions::Response &res)
Start the main calculation thread.
bool readParameters(ros::NodeHandle &n)
void jointsCB(const sensor_msgs::JointStateConstPtr &msg)
Update the joints of the robot.
bool get(const std::string &parent_name, const ros::NodeHandle &nh, const std::string &param_name, bool &value)


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