servo.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 : servo.cpp
35  * Project : moveit_servo
36  * Created : 3/9/2017
37  * Author : Brian O'Neil, Andy Zelenak, Blake Anderson
38  */
39 
41 
43 #include <moveit_servo/servo.h>
44 
45 static const std::string LOGNAME = "servo_node";
46 
47 namespace moveit_servo
48 {
49 namespace
50 {
51 constexpr double ROBOT_STATE_WAIT_TIME = 10.0; // seconds
52 } // namespace
53 
54 Servo::Servo(ros::NodeHandle& nh, const planning_scene_monitor::PlanningSceneMonitorPtr& planning_scene_monitor)
55  : nh_(nh), planning_scene_monitor_(planning_scene_monitor)
56 {
57  // Read ROS parameters, typically from YAML file
58  if (!readParameters())
59  exit(EXIT_FAILURE);
60 
61  // Async spinner is needed to receive messages to wait for the robot state to be complete
63  spinner.start();
64 
65  // Confirm the planning scene monitor is ready to be used
66  if (!planning_scene_monitor_->getStateMonitor())
67  {
69  }
70  planning_scene_monitor->getStateMonitor()->enableCopyDynamics(true);
71 
72  if (!planning_scene_monitor_->getStateMonitor()->waitForCompleteState(parameters_.move_group_name,
73  ROBOT_STATE_WAIT_TIME))
74  {
75  ROS_FATAL_NAMED(LOGNAME, "Timeout waiting for current state");
76  exit(EXIT_FAILURE);
77  }
78 
79  servo_calcs_ = std::make_unique<ServoCalcs>(nh_, parameters_, planning_scene_monitor_);
80 
81  collision_checker_ = std::make_unique<CollisionCheck>(nh_, parameters_, planning_scene_monitor_);
82 }
83 
84 // Read ROS parameters, typically from YAML file
86 {
87  std::size_t error = 0;
88 
89  ros::NodeHandle nh("~"); // Load all parameters w.r.t. to node's private namespace
90 
91  error += !rosparam_shortcuts::get(LOGNAME, nh, "publish_period", parameters_.publish_period);
92  error += !rosparam_shortcuts::get(LOGNAME, nh, "collision_check_rate", parameters_.collision_check_rate);
93  error += !rosparam_shortcuts::get(LOGNAME, nh, "num_outgoing_halt_msgs_to_publish",
95  error += !rosparam_shortcuts::get(LOGNAME, nh, "scale/linear", parameters_.linear_scale);
96  error += !rosparam_shortcuts::get(LOGNAME, nh, "scale/rotational", parameters_.rotational_scale);
97  error += !rosparam_shortcuts::get(LOGNAME, nh, "scale/joint", parameters_.joint_scale);
98  error += !rosparam_shortcuts::get(LOGNAME, nh, "low_pass_filter_coeff", parameters_.low_pass_filter_coeff);
99  error += !rosparam_shortcuts::get(LOGNAME, nh, "joint_topic", parameters_.joint_topic);
100  error += !rosparam_shortcuts::get(LOGNAME, nh, "command_in_type", parameters_.command_in_type);
101  error += !rosparam_shortcuts::get(LOGNAME, nh, "cartesian_command_in_topic", parameters_.cartesian_command_in_topic);
102  error += !rosparam_shortcuts::get(LOGNAME, nh, "joint_command_in_topic", parameters_.joint_command_in_topic);
103  error += !rosparam_shortcuts::get(LOGNAME, nh, "robot_link_command_frame", parameters_.robot_link_command_frame);
104  error += !rosparam_shortcuts::get(LOGNAME, nh, "incoming_command_timeout", parameters_.incoming_command_timeout);
105  error +=
106  !rosparam_shortcuts::get(LOGNAME, nh, "lower_singularity_threshold", parameters_.lower_singularity_threshold);
107  error += !rosparam_shortcuts::get(LOGNAME, nh, "hard_stop_singularity_threshold",
109  error += !rosparam_shortcuts::get(LOGNAME, nh, "move_group_name", parameters_.move_group_name);
110  error += !rosparam_shortcuts::get(LOGNAME, nh, "planning_frame", parameters_.planning_frame);
111  error += !rosparam_shortcuts::get(LOGNAME, nh, "ee_frame_name", parameters_.ee_frame_name);
112  error += !rosparam_shortcuts::get(LOGNAME, nh, "use_gazebo", parameters_.use_gazebo);
113  error += !rosparam_shortcuts::get(LOGNAME, nh, "joint_limit_margin", parameters_.joint_limit_margin);
114  error += !rosparam_shortcuts::get(LOGNAME, nh, "command_out_topic", parameters_.command_out_topic);
115  error += !rosparam_shortcuts::get(LOGNAME, nh, "command_out_type", parameters_.command_out_type);
116  error += !rosparam_shortcuts::get(LOGNAME, nh, "publish_joint_positions", parameters_.publish_joint_positions);
117  error += !rosparam_shortcuts::get(LOGNAME, nh, "publish_joint_velocities", parameters_.publish_joint_velocities);
118  error +=
119  !rosparam_shortcuts::get(LOGNAME, nh, "publish_joint_accelerations", parameters_.publish_joint_accelerations);
120 
121  // Parameters for collision checking
122  error += !rosparam_shortcuts::get(LOGNAME, nh, "check_collisions", parameters_.check_collisions);
123  error += !rosparam_shortcuts::get(LOGNAME, nh, "collision_check_type", parameters_.collision_check_type);
124  bool have_self_collision_proximity_threshold = rosparam_shortcuts::get(
125  LOGNAME, nh, "self_collision_proximity_threshold", parameters_.self_collision_proximity_threshold);
126  bool have_scene_collision_proximity_threshold = rosparam_shortcuts::get(
127  LOGNAME, nh, "scene_collision_proximity_threshold", parameters_.scene_collision_proximity_threshold);
128 
129  double collision_proximity_threshold;
130  // 'collision_proximity_threshold' parameter was removed, replaced with separate self- and scene-collision proximity
131  // thresholds
132  // TODO(JStech): remove this deprecation warning in ROS Noetic; simplify error case handling
133  if (nh.hasParam("collision_proximity_threshold") &&
134  rosparam_shortcuts::get(LOGNAME, nh, "collision_proximity_threshold", collision_proximity_threshold))
135  {
136  ROS_WARN_NAMED(LOGNAME, "'collision_proximity_threshold' parameter is deprecated, and has been replaced by separate"
137  "'self_collision_proximity_threshold' and 'scene_collision_proximity_threshold' "
138  "parameters. Please update the servoing yaml file.");
139  if (!have_self_collision_proximity_threshold)
140  {
141  parameters_.self_collision_proximity_threshold = collision_proximity_threshold;
142  have_self_collision_proximity_threshold = true;
143  }
144  if (!have_scene_collision_proximity_threshold)
145  {
146  parameters_.scene_collision_proximity_threshold = collision_proximity_threshold;
147  have_scene_collision_proximity_threshold = true;
148  }
149  }
150  error += !have_self_collision_proximity_threshold;
151  error += !have_scene_collision_proximity_threshold;
152  error += !rosparam_shortcuts::get(LOGNAME, nh, "collision_distance_safety_factor",
154  error += !rosparam_shortcuts::get(LOGNAME, nh, "min_allowable_collision_distance",
156 
157  // This parameter name was changed recently.
158  // Try retrieving from the correct name. If it fails, then try the deprecated name.
159  // TODO(andyz): remove this deprecation warning in ROS Noetic
160  if (!rosparam_shortcuts::get(LOGNAME, nh, "status_topic", parameters_.status_topic))
161  {
162  ROS_WARN_NAMED(LOGNAME, "'status_topic' parameter is missing. Recently renamed from 'warning_topic'. Please update "
163  "the servoing yaml file.");
164  error += !rosparam_shortcuts::get(LOGNAME, nh, "warning_topic", parameters_.status_topic);
165  }
166 
167  if (nh.hasParam("low_latency_mode"))
168  {
169  error += !rosparam_shortcuts::get(LOGNAME, nh, "low_latency_mode", parameters_.low_latency_mode);
170  }
171  else
172  {
173  ROS_WARN_NAMED(LOGNAME, "'low_latency_mode' is a new parameter that runs servo calc immediately after receiving "
174  "input. Setting to the default value of false.");
176  }
177 
179 
180  // Input checking
181  if (parameters_.publish_period <= 0.)
182  {
183  ROS_WARN_NAMED(LOGNAME, "Parameter 'publish_period' should be "
184  "greater than zero. Check yaml file.");
185  return false;
186  }
188  {
190  "Parameter 'num_outgoing_halt_msgs_to_publish' should be greater than zero. Check yaml file.");
191  return false;
192  }
194  {
195  ROS_WARN_NAMED(LOGNAME, "Parameter 'hard_stop_singularity_threshold' "
196  "should be greater than 'lower_singularity_threshold.' "
197  "Check yaml file.");
198  return false;
199  }
201  {
202  ROS_WARN_NAMED(LOGNAME, "Parameters 'hard_stop_singularity_threshold' "
203  "and 'lower_singularity_threshold' should be "
204  "greater than zero. Check yaml file.");
205  return false;
206  }
208  {
209  ROS_WARN_NAMED(LOGNAME, "Parameter 'low_pass_filter_coeff' should be "
210  "greater than zero. Check yaml file.");
211  return false;
212  }
214  {
215  ROS_WARN_NAMED(LOGNAME, "Parameter 'joint_limit_margin' should be "
216  "greater than or equal to zero. Check yaml file.");
217  return false;
218  }
219  if (parameters_.command_in_type != "unitless" && parameters_.command_in_type != "speed_units")
220  {
221  ROS_WARN_NAMED(LOGNAME, "command_in_type should be 'unitless' or "
222  "'speed_units'. Check yaml file.");
223  return false;
224  }
225  if (parameters_.command_out_type != "trajectory_msgs/JointTrajectory" &&
226  parameters_.command_out_type != "std_msgs/Float64MultiArray")
227  {
228  ROS_WARN_NAMED(LOGNAME, "Parameter command_out_type should be "
229  "'trajectory_msgs/JointTrajectory' or "
230  "'std_msgs/Float64MultiArray'. Check yaml file.");
231  return false;
232  }
235  {
236  ROS_WARN_NAMED(LOGNAME, "At least one of publish_joint_positions / "
237  "publish_joint_velocities / "
238  "publish_joint_accelerations must be true. Check "
239  "yaml file.");
240  return false;
241  }
242  if ((parameters_.command_out_type == "std_msgs/Float64MultiArray") && parameters_.publish_joint_positions &&
244  {
245  ROS_WARN_NAMED(LOGNAME, "When publishing a std_msgs/Float64MultiArray, "
246  "you must select positions OR velocities.");
247  return false;
248  }
249  // Collision checking
250  if (parameters_.collision_check_type != "threshold_distance" && parameters_.collision_check_type != "stop_distance")
251  {
252  ROS_WARN_NAMED(LOGNAME, "collision_check_type must be 'threshold_distance' or 'stop_distance'");
253  return false;
254  }
256  {
257  ROS_WARN_NAMED(LOGNAME, "Parameter 'self_collision_proximity_threshold' should be "
258  "greater than zero. Check yaml file.");
259  return false;
260  }
262  {
263  ROS_WARN_NAMED(LOGNAME, "Parameter 'scene_collision_proximity_threshold' should be "
264  "greater than zero. Check yaml file.");
265  return false;
266  }
268  {
269  ROS_WARN_NAMED(LOGNAME, "Parameter 'self_collision_proximity_threshold' should probably be less "
270  "than or equal to 'scene_collision_proximity_threshold'. Check yaml file.");
271  }
273  {
274  ROS_WARN_NAMED(LOGNAME, "Parameter 'collision_check_rate' should be "
275  "greater than zero. Check yaml file.");
276  return false;
277  }
279  {
280  ROS_WARN_NAMED(LOGNAME, "Parameter 'collision_distance_safety_factor' should be "
281  "greater than or equal to 1. Check yaml file.");
282  return false;
283  }
285  {
286  ROS_WARN_NAMED(LOGNAME, "Parameter 'min_allowable_collision_distance' should be "
287  "greater than zero. Check yaml file.");
288  return false;
289  }
290 
291  return true;
292 }
293 
295 {
296  setPaused(false);
297 
298  // Crunch the numbers in this timer
299  servo_calcs_->start();
300 
301  // Check collisions in this timer
303  collision_checker_->start();
304 }
305 
307 {
308  setPaused(true);
309 }
310 
311 void Servo::setPaused(bool paused)
312 {
313  servo_calcs_->setPaused(paused);
314  collision_checker_->setPaused(paused);
315 }
316 
317 bool Servo::getCommandFrameTransform(Eigen::Isometry3d& transform)
318 {
319  return servo_calcs_->getCommandFrameTransform(transform);
320 }
321 
322 bool Servo::getCommandFrameTransform(geometry_msgs::TransformStamped& transform)
323 {
324  return servo_calcs_->getCommandFrameTransform(transform);
325 }
326 
327 bool Servo::getEEFrameTransform(Eigen::Isometry3d& transform)
328 {
329  return servo_calcs_->getEEFrameTransform(transform);
330 }
331 
332 bool Servo::getEEFrameTransform(geometry_msgs::TransformStamped& transform)
333 {
334  return servo_calcs_->getEEFrameTransform(transform);
335 }
336 
338 {
339  return parameters_;
340 }
341 
342 } // namespace moveit_servo
planning_scene_monitor
servo.h
moveit_servo::ServoParameters::use_gazebo
bool use_gazebo
Definition: servo_parameters.h:106
moveit_servo::Servo::servo_calcs_
std::unique_ptr< ServoCalcs > servo_calcs_
Definition: servo.h:184
rosparam_shortcuts::get
bool get(const std::string &parent_name, const ros::NodeHandle &nh, const std::string &param_name, bool &value)
ros::AsyncSpinner
moveit_servo::ServoParameters::incoming_command_timeout
double incoming_command_timeout
Definition: servo_parameters.h:103
moveit_servo::Servo::setPaused
void setPaused(bool paused)
Pause or unpause processing servo commands while keeping the timers alive.
Definition: servo.cpp:311
moveit_servo::Servo::Servo
Servo(ros::NodeHandle &nh, const planning_scene_monitor::PlanningSceneMonitorPtr &planning_scene_monitor)
Definition: servo.cpp:54
moveit_servo::ServoParameters::linear_scale
double linear_scale
Definition: servo_parameters.h:96
moveit_servo::Servo::getEEFrameTransform
bool getEEFrameTransform(Eigen::Isometry3d &transform)
Definition: servo.cpp:327
moveit_servo::Servo::getParameters
const ServoParameters & getParameters() const
Get the parameters used by servo node.
Definition: servo.cpp:337
moveit_servo::ServoParameters::self_collision_proximity_threshold
double self_collision_proximity_threshold
Definition: servo_parameters.h:116
moveit_servo::ServoParameters::joint_command_in_topic
std::string joint_command_in_topic
Definition: servo_parameters.h:93
moveit_servo::ServoParameters::num_outgoing_halt_msgs_to_publish
int num_outgoing_halt_msgs_to_publish
Definition: servo_parameters.h:105
moveit_servo::ServoParameters::move_group_name
std::string move_group_name
Definition: servo_parameters.h:85
transform
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
moveit_servo::ServoParameters::command_out_type
std::string command_out_type
Definition: servo_parameters.h:95
ROS_FATAL_NAMED
#define ROS_FATAL_NAMED(name,...)
make_shared_from_pool.h
moveit_servo::ServoParameters::status_topic
std::string status_topic
Definition: servo_parameters.h:92
moveit_servo::ServoParameters::planning_frame
std::string planning_frame
Definition: servo_parameters.h:90
moveit_servo::ServoParameters::joint_scale
double joint_scale
Definition: servo_parameters.h:98
moveit_servo::ServoParameters::collision_check_type
std::string collision_check_type
Definition: servo_parameters.h:113
moveit_servo::Servo::collision_checker_
std::unique_ptr< CollisionCheck > collision_checker_
Definition: servo.h:185
spinner
void spinner()
moveit_servo::Servo::nh_
ros::NodeHandle nh_
Definition: servo.h:176
moveit_servo::ServoParameters
Definition: servo_parameters.h:83
moveit_servo::ServoParameters::joint_limit_margin
double joint_limit_margin
Definition: servo_parameters.h:104
moveit_servo::ServoParameters::rotational_scale
double rotational_scale
Definition: servo_parameters.h:97
moveit_servo::ServoParameters::ee_frame_name
std::string ee_frame_name
Definition: servo_parameters.h:91
moveit_servo
Definition: collision_check.h:50
moveit_servo::ServoParameters::low_latency_mode
bool low_latency_mode
Definition: servo_parameters.h:110
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
rosparam_shortcuts.h
moveit_servo::ServoParameters::cartesian_command_in_topic
std::string cartesian_command_in_topic
Definition: servo_parameters.h:87
moveit_servo::ServoParameters::scene_collision_proximity_threshold
double scene_collision_proximity_threshold
Definition: servo_parameters.h:115
moveit_servo::ServoParameters::collision_check_rate
double collision_check_rate
Definition: servo_parameters.h:114
moveit_servo::ServoParameters::lower_singularity_threshold
double lower_singularity_threshold
Definition: servo_parameters.h:99
moveit_servo::ServoParameters::min_allowable_collision_distance
double min_allowable_collision_distance
Definition: servo_parameters.h:118
moveit_servo::ServoParameters::hard_stop_singularity_threshold
double hard_stop_singularity_threshold
Definition: servo_parameters.h:100
moveit_servo::Servo::readParameters
bool readParameters()
Definition: servo.cpp:85
moveit_servo::ServoParameters::collision_distance_safety_factor
double collision_distance_safety_factor
Definition: servo_parameters.h:117
moveit_servo::Servo::~Servo
~Servo()
Definition: servo.cpp:306
moveit_servo::ServoParameters::publish_joint_positions
bool publish_joint_positions
Definition: servo_parameters.h:107
moveit_servo::ServoParameters::robot_link_command_frame
std::string robot_link_command_frame
Definition: servo_parameters.h:88
moveit_servo::Servo::getCommandFrameTransform
bool getCommandFrameTransform(Eigen::Isometry3d &transform)
Definition: servo.cpp:317
moveit_servo::ServoParameters::joint_topic
std::string joint_topic
Definition: servo_parameters.h:86
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
LOGNAME
static const std::string LOGNAME
Definition: servo.cpp:45
moveit_servo::ServoParameters::publish_period
double publish_period
Definition: servo_parameters.h:102
moveit_servo::ServoParameters::command_in_type
std::string command_in_type
Definition: servo_parameters.h:94
moveit_servo::ServoParameters::command_out_topic
std::string command_out_topic
Definition: servo_parameters.h:89
moveit_servo::ServoParameters::check_collisions
bool check_collisions
Definition: servo_parameters.h:112
moveit_servo::ServoParameters::publish_joint_velocities
bool publish_joint_velocities
Definition: servo_parameters.h:108
moveit_servo::Servo::planning_scene_monitor_
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
Definition: servo.h:179
moveit_servo::ServoParameters::low_pass_filter_coeff
double low_pass_filter_coeff
Definition: servo_parameters.h:101
rosparam_shortcuts::shutdownIfError
void shutdownIfError(const std::string &parent_name, std::size_t error_count)
ros::NodeHandle
moveit_servo::ServoParameters::publish_joint_accelerations
bool publish_joint_accelerations
Definition: servo_parameters.h:109
moveit_servo::Servo::start
void start()
start servo node
Definition: servo.cpp:294
moveit_servo::Servo::parameters_
ServoParameters parameters_
Definition: servo.h:182


moveit_servo
Author(s): Brian O'Neil, Andy Zelenak , Blake Anderson, Alexander Rössler , Tyler Weaver
autogenerated on Sat May 3 2025 02:27:56