pose_tracking.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2020, PickNik 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
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of PickNik LLC nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
36 
37 namespace
38 {
39 constexpr char LOGNAME[] = "pose_tracking";
40 constexpr double DEFAULT_LOOP_RATE = 100; // Hz
41 constexpr double ROS_STARTUP_WAIT = 10; // sec
42 } // namespace
43 
44 namespace moveit_servo
45 {
47  const planning_scene_monitor::PlanningSceneMonitorPtr& planning_scene_monitor)
48  : nh_(nh)
49  , planning_scene_monitor_(planning_scene_monitor)
50  , loop_rate_(DEFAULT_LOOP_RATE)
51  , transform_listener_(transform_buffer_)
52  , stop_requested_(false)
53  , angular_error_(boost::none)
54 {
55  readROSParams();
56 
57  robot_model_ = planning_scene_monitor_->getRobotModel();
58  joint_model_group_ = robot_model_->getJointModelGroup(move_group_name_);
59 
60  // Initialize PID controllers
65 
66  // Use the C++ interface that Servo provides
67  servo_ = std::make_unique<moveit_servo::Servo>(nh_, planning_scene_monitor_);
68  servo_->start();
69 
70  // Connect to Servo ROS interfaces
72  nh_.subscribe<geometry_msgs::PoseStamped>("target_pose", 1, &PoseTracking::targetPoseCallback, this);
73 
74  // Publish outgoing twist commands to the Servo object
76  nh_.advertise<geometry_msgs::TwistStamped>(servo_->getParameters().cartesian_command_in_topic, 1);
77 }
78 
79 PoseTrackingStatusCode PoseTracking::moveToPose(const Eigen::Vector3d& positional_tolerance,
80  const double angular_tolerance, const double target_pose_timeout)
81 {
82  // Reset stop requested flag before starting motions
83  stop_requested_ = false;
84  // Wait a bit for a target pose message to arrive.
85  // The target pose may get updated by new messages as the robot moves (in a callback function).
86  const ros::Time start_time = ros::Time::now();
87  while ((!haveRecentTargetPose(target_pose_timeout) || !haveRecentEndEffectorPose(target_pose_timeout)) &&
88  ((ros::Time::now() - start_time).toSec() < target_pose_timeout))
89  {
90  if (servo_->getCommandFrameTransform(command_frame_transform_))
91  {
93  }
94  ros::Duration(0.001).sleep();
95  }
96 
97  if (!haveRecentTargetPose(target_pose_timeout))
98  {
99  ROS_ERROR_STREAM_NAMED(LOGNAME, "The target pose was not updated recently. Aborting.");
101  }
102 
103  // Continue sending PID controller output to Servo until one of the following conditions is met:
104  // - Goal tolerance is satisfied
105  // - Target pose becomes outdated
106  // - Command frame transform becomes outdated
107  // - Another thread requested a stop
108  while (ros::ok() && !satisfiesPoseTolerance(positional_tolerance, angular_tolerance))
109  {
110  // Attempt to update robot pose
111  if (servo_->getCommandFrameTransform(command_frame_transform_))
112  {
114  }
115 
116  // Check that end-effector pose (command frame transform) is recent enough.
117  if (!haveRecentEndEffectorPose(target_pose_timeout))
118  {
119  ROS_ERROR_STREAM_NAMED(LOGNAME, "The end effector pose was not updated in time. Aborting.");
122  }
123 
124  if (stop_requested_)
125  {
126  ROS_INFO_STREAM_NAMED(LOGNAME, "Halting servo motion, a stop was requested.");
129  }
130 
131  // Compute servo command from PID controller output and send it to the Servo object, for execution
133 
134  if (!loop_rate_.sleep())
135  {
136  ROS_WARN_STREAM_THROTTLE_NAMED(1, LOGNAME, "Target control rate was missed");
137  }
138  }
139 
142 }
143 
145 {
146  ros::NodeHandle nh("~");
147 
148  // Wait for ROS parameters to load
149  ros::Time begin = ros::Time::now();
150  while (ros::ok() && !nh.hasParam("planning_frame") && ((ros::Time::now() - begin).toSec() < ROS_STARTUP_WAIT))
151  {
152  ROS_WARN_STREAM_NAMED(LOGNAME, "Waiting for parameter: "
153  << "planning_frame");
154  ros::Duration(0.1).sleep();
155  }
156 
157  std::size_t error = 0;
158 
159  error += !rosparam_shortcuts::get(LOGNAME, nh, "planning_frame", planning_frame_);
160  error += !rosparam_shortcuts::get(LOGNAME, nh, "move_group_name", move_group_name_);
161  if (!planning_scene_monitor_->getRobotModel()->hasJointModelGroup(move_group_name_))
162  {
163  ++error;
164  ROS_ERROR_STREAM_NAMED(LOGNAME, "Unable to find the specified joint model group: " << move_group_name_);
165  }
166 
167  double publish_period;
168  error += !rosparam_shortcuts::get(LOGNAME, nh, "publish_period", publish_period);
169  loop_rate_ = ros::Rate(1 / publish_period);
170 
171  x_pid_config_.dt = publish_period;
172  y_pid_config_.dt = publish_period;
173  z_pid_config_.dt = publish_period;
174  angular_pid_config_.dt = publish_period;
175 
176  double windup_limit;
177  error += !rosparam_shortcuts::get(LOGNAME, nh, "windup_limit", windup_limit);
178  x_pid_config_.windup_limit = windup_limit;
179  y_pid_config_.windup_limit = windup_limit;
180  z_pid_config_.windup_limit = windup_limit;
181  angular_pid_config_.windup_limit = windup_limit;
182 
183  error += !rosparam_shortcuts::get(LOGNAME, nh, "x_proportional_gain", x_pid_config_.k_p);
184  error += !rosparam_shortcuts::get(LOGNAME, nh, "y_proportional_gain", y_pid_config_.k_p);
185  error += !rosparam_shortcuts::get(LOGNAME, nh, "z_proportional_gain", z_pid_config_.k_p);
186  error += !rosparam_shortcuts::get(LOGNAME, nh, "x_integral_gain", x_pid_config_.k_i);
187  error += !rosparam_shortcuts::get(LOGNAME, nh, "y_integral_gain", y_pid_config_.k_i);
188  error += !rosparam_shortcuts::get(LOGNAME, nh, "z_integral_gain", z_pid_config_.k_i);
189  error += !rosparam_shortcuts::get(LOGNAME, nh, "x_derivative_gain", x_pid_config_.k_d);
190  error += !rosparam_shortcuts::get(LOGNAME, nh, "y_derivative_gain", y_pid_config_.k_d);
191  error += !rosparam_shortcuts::get(LOGNAME, nh, "z_derivative_gain", z_pid_config_.k_d);
192 
193  error += !rosparam_shortcuts::get(LOGNAME, nh, "angular_proportional_gain", angular_pid_config_.k_p);
194  error += !rosparam_shortcuts::get(LOGNAME, nh, "angular_integral_gain", angular_pid_config_.k_i);
195  error += !rosparam_shortcuts::get(LOGNAME, nh, "angular_derivative_gain", angular_pid_config_.k_d);
196 
198 }
199 
200 void PoseTracking::initializePID(const PIDConfig& pid_config, std::vector<control_toolbox::Pid>& pid_vector)
201 {
202  bool use_anti_windup = true;
203  pid_vector.push_back(control_toolbox::Pid(pid_config.k_p, pid_config.k_i, pid_config.k_d, pid_config.windup_limit,
204  -pid_config.windup_limit, use_anti_windup));
205 }
206 
207 bool PoseTracking::haveRecentTargetPose(const double timespan)
208 {
209  std::lock_guard<std::mutex> lock(target_pose_mtx_);
210  return ((ros::Time::now() - target_pose_.header.stamp).toSec() < timespan);
211 }
212 
213 bool PoseTracking::haveRecentEndEffectorPose(const double timespan)
214 {
215  return ((ros::Time::now() - command_frame_transform_stamp_).toSec() < timespan);
216 }
217 
218 bool PoseTracking::satisfiesPoseTolerance(const Eigen::Vector3d& positional_tolerance, const double angular_tolerance)
219 {
220  std::lock_guard<std::mutex> lock(target_pose_mtx_);
221  double x_error = target_pose_.pose.position.x - command_frame_transform_.translation()(0);
222  double y_error = target_pose_.pose.position.y - command_frame_transform_.translation()(1);
223  double z_error = target_pose_.pose.position.z - command_frame_transform_.translation()(2);
224 
225  // If uninitialized, likely haven't received the target pose yet.
226  if (!angular_error_)
227  return false;
228 
229  return ((std::abs(x_error) < positional_tolerance(0)) && (std::abs(y_error) < positional_tolerance(1)) &&
230  (std::abs(z_error) < positional_tolerance(2)) && (std::abs(*angular_error_) < angular_tolerance));
231 }
232 
233 void PoseTracking::targetPoseCallback(const geometry_msgs::PoseStampedConstPtr& msg)
234 {
235  std::lock_guard<std::mutex> lock(target_pose_mtx_);
236  target_pose_ = *msg;
237 
238  // If the target pose is not defined in planning frame, transform the target pose.
239  if (target_pose_.header.frame_id != planning_frame_)
240  {
241  try
242  {
243  geometry_msgs::TransformStamped target_to_planning_frame = transform_buffer_.lookupTransform(
244  planning_frame_, target_pose_.header.frame_id, ros::Time(0), ros::Duration(0.1));
245  tf2::doTransform(target_pose_, target_pose_, target_to_planning_frame);
246 
247  // Prevent doTransform from copying a stamp of 0, which will cause the haveRecentTargetPose check to fail servo motions
248  target_pose_.header.stamp = ros::Time::now();
249  }
250  catch (const tf2::TransformException& ex)
251  {
252  ROS_WARN_STREAM_NAMED(LOGNAME, ex.what());
253  return;
254  }
255  }
256 }
257 
258 geometry_msgs::TwistStampedConstPtr PoseTracking::calculateTwistCommand()
259 {
260  // use the shared pool to create a message more efficiently
261  auto msg = moveit::util::make_shared_from_pool<geometry_msgs::TwistStamped>();
262 
263  // Get twist components from PID controllers
264  geometry_msgs::Twist& twist = msg->twist;
265  Eigen::Quaterniond q_desired;
266 
267  // Scope mutex locking only to operations which require access to target pose.
268  {
269  std::lock_guard<std::mutex> lock(target_pose_mtx_);
270  msg->header.frame_id = target_pose_.header.frame_id;
271 
272  // Position
273  twist.linear.x = cartesian_position_pids_[0].computeCommand(
274  target_pose_.pose.position.x - command_frame_transform_.translation()(0), loop_rate_.expectedCycleTime());
275  twist.linear.y = cartesian_position_pids_[1].computeCommand(
276  target_pose_.pose.position.y - command_frame_transform_.translation()(1), loop_rate_.expectedCycleTime());
277  twist.linear.z = cartesian_position_pids_[2].computeCommand(
278  target_pose_.pose.position.z - command_frame_transform_.translation()(2), loop_rate_.expectedCycleTime());
279 
280  // Orientation algorithm:
281  // - Find the orientation error as a quaternion: q_error = q_desired * q_current ^ -1
282  // - Use the angle-axis PID controller to calculate an angular rate
283  // - Convert to angular velocity for the TwistStamped message
284  q_desired = Eigen::Quaterniond(target_pose_.pose.orientation.w, target_pose_.pose.orientation.x,
285  target_pose_.pose.orientation.y, target_pose_.pose.orientation.z);
286  }
287 
288  Eigen::Quaterniond q_current(command_frame_transform_.rotation());
289  Eigen::Quaterniond q_error = q_desired * q_current.inverse();
290 
291  // Convert axis-angle to angular velocity
292  Eigen::AngleAxisd axis_angle(q_error);
293  // Cache the angular error, for rotation tolerance checking
294  angular_error_ = axis_angle.angle();
295  double ang_vel_magnitude =
297  twist.angular.x = ang_vel_magnitude * axis_angle.axis()[0];
298  twist.angular.y = ang_vel_magnitude * axis_angle.axis()[1];
299  twist.angular.z = ang_vel_magnitude * axis_angle.axis()[2];
300 
301  msg->header.stamp = ros::Time::now();
302 
303  return msg;
304 }
305 
307 {
308  stop_requested_ = true;
309 
310  // Send a 0 command to Servo to halt arm motion
311  auto msg = moveit::util::make_shared_from_pool<geometry_msgs::TwistStamped>();
312  {
313  std::lock_guard<std::mutex> lock(target_pose_mtx_);
314  msg->header.frame_id = target_pose_.header.frame_id;
315  }
316  msg->header.stamp = ros::Time::now();
318 }
319 
321 {
322  stopMotion();
323  stop_requested_ = false;
324  angular_error_ = boost::none;
325 
326  // Reset error integrals and previous errors of PID controllers
327  cartesian_position_pids_[0].reset();
328  cartesian_position_pids_[1].reset();
329  cartesian_position_pids_[2].reset();
330  cartesian_orientation_pids_[0].reset();
331 }
332 
333 void PoseTracking::updatePIDConfig(const double x_proportional_gain, const double x_integral_gain,
334  const double x_derivative_gain, const double y_proportional_gain,
335  const double y_integral_gain, const double y_derivative_gain,
336  const double z_proportional_gain, const double z_integral_gain,
337  const double z_derivative_gain, const double angular_proportional_gain,
338  const double angular_integral_gain, const double angular_derivative_gain)
339 {
340  stopMotion();
341 
342  x_pid_config_.k_p = x_proportional_gain;
343  x_pid_config_.k_i = x_integral_gain;
344  x_pid_config_.k_d = x_derivative_gain;
345  y_pid_config_.k_p = y_proportional_gain;
346  y_pid_config_.k_i = y_integral_gain;
347  y_pid_config_.k_d = y_derivative_gain;
348  z_pid_config_.k_p = z_proportional_gain;
349  z_pid_config_.k_i = z_integral_gain;
350  z_pid_config_.k_d = z_derivative_gain;
351 
352  angular_pid_config_.k_p = angular_proportional_gain;
353  angular_pid_config_.k_i = angular_integral_gain;
354  angular_pid_config_.k_d = angular_derivative_gain;
355 
356  cartesian_position_pids_.clear();
362 
364 }
365 
366 void PoseTracking::getPIDErrors(double& x_error, double& y_error, double& z_error, double& orientation_error)
367 {
368  double dummy1, dummy2;
369  cartesian_position_pids_.at(0).getCurrentPIDErrors(&x_error, &dummy1, &dummy2);
370  cartesian_position_pids_.at(1).getCurrentPIDErrors(&y_error, &dummy1, &dummy2);
371  cartesian_position_pids_.at(2).getCurrentPIDErrors(&z_error, &dummy1, &dummy2);
372  cartesian_orientation_pids_.at(0).getCurrentPIDErrors(&orientation_error, &dummy1, &dummy2);
373 }
374 
376 {
377  std::lock_guard<std::mutex> lock(target_pose_mtx_);
378  target_pose_ = geometry_msgs::PoseStamped();
379  target_pose_.header.stamp = ros::Time(0);
380 }
381 
382 bool PoseTracking::getCommandFrameTransform(geometry_msgs::TransformStamped& transform)
383 {
384  return servo_->getCommandFrameTransform(transform);
385 }
386 } // namespace moveit_servo
moveit_servo::PIDConfig::k_d
double k_d
Definition: pose_tracking.h:125
ROS_WARN_STREAM_THROTTLE_NAMED
#define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args)
moveit_servo::PoseTracking::haveRecentTargetPose
bool haveRecentTargetPose(const double timeout)
Return true if a target pose has been received within timeout [seconds].
Definition: pose_tracking.cpp:207
planning_scene_monitor
moveit_servo::PoseTrackingStatusCode::NO_RECENT_END_EFFECTOR_POSE
@ NO_RECENT_END_EFFECTOR_POSE
moveit_servo::PoseTracking::planning_scene_monitor_
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
Definition: pose_tracking.h:186
moveit_servo::PoseTracking::haveRecentEndEffectorPose
bool haveRecentEndEffectorPose(const double timeout)
Return true if an end effector pose has been received within timeout [seconds].
Definition: pose_tracking.cpp:213
ros::Rate::expectedCycleTime
Duration expectedCycleTime() const
moveit_servo::PoseTracking::getPIDErrors
void getPIDErrors(double &x_error, double &y_error, double &z_error, double &orientation_error)
Definition: pose_tracking.cpp:366
moveit_servo::PoseTrackingStatusCode::NO_RECENT_TARGET_POSE
@ NO_RECENT_TARGET_POSE
moveit_servo::PoseTracking::resetTargetPose
void resetTargetPose()
Re-initialize the target pose to an empty message. Can be used to reset motion between waypoints.
Definition: pose_tracking.cpp:375
rosparam_shortcuts::get
bool get(const std::string &parent_name, const ros::NodeHandle &nh, const std::string &param_name, bool &value)
moveit_servo::PoseTracking::cartesian_orientation_pids_
std::vector< control_toolbox::Pid > cartesian_orientation_pids_
Definition: pose_tracking.h:198
moveit_servo::PoseTracking::nh_
ros::NodeHandle nh_
Definition: pose_tracking.h:184
moveit_servo::PoseTracking::cartesian_position_pids_
std::vector< control_toolbox::Pid > cartesian_position_pids_
Definition: pose_tracking.h:197
moveit_servo::PIDConfig::k_i
double k_i
Definition: pose_tracking.h:124
moveit_servo::PoseTracking::move_group_name_
std::string move_group_name_
Definition: pose_tracking.h:190
moveit_servo::PoseTracking::y_pid_config_
PIDConfig y_pid_config_
Definition: pose_tracking.h:200
moveit_servo::PoseTracking::target_pose_
geometry_msgs::PoseStamped target_pose_
Definition: pose_tracking.h:205
boost
transform
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
moveit_servo::PIDConfig::windup_limit
double windup_limit
Definition: pose_tracking.h:126
moveit_servo::PoseTracking::command_frame_transform_stamp_
ros::Time command_frame_transform_stamp_
Definition: pose_tracking.h:204
moveit_servo::PoseTrackingStatusCode::SUCCESS
@ SUCCESS
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
moveit_servo::PoseTracking::doPostMotionReset
void doPostMotionReset()
Reset flags and PID controllers after a motion completes.
Definition: pose_tracking.cpp:320
ros::ok
ROSCPP_DECL bool ok()
moveit_servo::PoseTracking::satisfiesPoseTolerance
bool satisfiesPoseTolerance(const Eigen::Vector3d &positional_tolerance, const double angular_tolerance)
Check if XYZ, roll/pitch/yaw tolerances are satisfied.
Definition: pose_tracking.cpp:218
moveit_servo::PoseTracking::z_pid_config_
PIDConfig z_pid_config_
Definition: pose_tracking.h:200
moveit_servo::PoseTracking::updatePIDConfig
void updatePIDConfig(const double x_proportional_gain, const double x_integral_gain, const double x_derivative_gain, const double y_proportional_gain, const double y_integral_gain, const double y_derivative_gain, const double z_proportional_gain, const double z_integral_gain, const double z_derivative_gain, const double angular_proportional_gain, const double angular_integral_gain, const double angular_derivative_gain)
Change PID parameters. Motion is stopped before the udpate.
Definition: pose_tracking.cpp:333
LOGNAME
static const char LOGNAME[]
Definition: collision_check.cpp:45
moveit_servo::PIDConfig::dt
double dt
Definition: pose_tracking.h:122
moveit_servo::PoseTracking::robot_model_
robot_model::RobotModelConstPtr robot_model_
Definition: pose_tracking.h:187
moveit_servo::PoseTracking::calculateTwistCommand
geometry_msgs::TwistStampedConstPtr calculateTwistCommand()
Use PID controllers to calculate a full spatial velocity toward a pose.
Definition: pose_tracking.cpp:258
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
moveit_servo
Definition: collision_check.h:50
moveit_servo::PoseTrackingStatusCode
PoseTrackingStatusCode
Definition: pose_tracking.h:97
moveit_servo::PoseTracking::command_frame_transform_
Eigen::Isometry3d command_frame_transform_
Definition: pose_tracking.h:203
moveit_servo::PoseTracking::stopMotion
void stopMotion()
A method for a different thread to stop motion and return early from control loop.
Definition: pose_tracking.cpp:306
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
moveit_servo::PoseTrackingStatusCode::STOP_REQUESTED
@ STOP_REQUESTED
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
moveit_servo::PoseTracking::loop_rate_
ros::Rate loop_rate_
Definition: pose_tracking.h:192
ros::Rate::sleep
bool sleep()
moveit_servo::PoseTracking::angular_error_
boost::optional< double > angular_error_
Definition: pose_tracking.h:220
moveit_servo::PoseTracking::x_pid_config_
PIDConfig x_pid_config_
Definition: pose_tracking.h:200
ROS_WARN_STREAM_NAMED
#define ROS_WARN_STREAM_NAMED(name, args)
pose_tracking.h
moveit_servo::PoseTracking::twist_stamped_pub_
ros::Publisher twist_stamped_pub_
Definition: pose_tracking.h:195
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
moveit_servo::PoseTracking::target_pose_mtx_
std::mutex target_pose_mtx_
Definition: pose_tracking.h:206
ros::Time
tf2::doTransform
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
moveit_servo::PIDConfig::k_p
double k_p
Definition: pose_tracking.h:123
control_toolbox::Pid
moveit_servo::PoseTracking::stop_requested_
std::atomic< bool > stop_requested_
Definition: pose_tracking.h:218
ROS_INFO_STREAM_NAMED
#define ROS_INFO_STREAM_NAMED(name, args)
moveit_servo::PoseTracking::angular_pid_config_
PIDConfig angular_pid_config_
Definition: pose_tracking.h:200
ros::Rate
ros::Duration::sleep
bool sleep() const
moveit_servo::PoseTracking::joint_model_group_
const moveit::core::JointModelGroup * joint_model_group_
Definition: pose_tracking.h:188
moveit_servo::PoseTracking::moveToPose
PoseTrackingStatusCode moveToPose(const Eigen::Vector3d &positional_tolerance, const double angular_tolerance, const double target_pose_timeout)
Definition: pose_tracking.cpp:79
moveit_servo::PoseTracking::target_pose_sub_
ros::Subscriber target_pose_sub_
Definition: pose_tracking.h:209
tf2::TransformException
moveit_servo::PoseTracking::transform_buffer_
tf2_ros::Buffer transform_buffer_
Definition: pose_tracking.h:211
moveit_servo::PoseTracking::PoseTracking
PoseTracking(const ros::NodeHandle &nh, const planning_scene_monitor::PlanningSceneMonitorPtr &planning_scene_monitor)
Constructor. Loads ROS parameters under the given namespace.
Definition: pose_tracking.cpp:46
ros::Duration
moveit_servo::PoseTracking::readROSParams
void readROSParams()
Load ROS parameters for controller settings.
Definition: pose_tracking.cpp:144
moveit_servo::PoseTracking::targetPoseCallback
void targetPoseCallback(const geometry_msgs::PoseStampedConstPtr &msg)
Subscribe to the target pose on this topic.
Definition: pose_tracking.cpp:233
rosparam_shortcuts::shutdownIfError
void shutdownIfError(const std::string &parent_name, std::size_t error_count)
moveit_servo::PIDConfig
Definition: pose_tracking.h:87
moveit_servo::PoseTracking::servo_
std::unique_ptr< moveit_servo::Servo > servo_
Definition: pose_tracking.h:151
tf2_ros::Buffer::lookupTransform
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const ros::Time &target_time, const std::string &source_frame, const ros::Time &source_time, const std::string &fixed_frame, const ros::Duration timeout) const
moveit_servo::PoseTracking::planning_frame_
std::string planning_frame_
Definition: pose_tracking.h:215
ros::NodeHandle
ros::Time::now
static Time now()
moveit_servo::PoseTracking::getCommandFrameTransform
bool getCommandFrameTransform(geometry_msgs::TransformStamped &transform)
Definition: pose_tracking.cpp:382
moveit_servo::PoseTracking::initializePID
void initializePID(const PIDConfig &pid_config, std::vector< control_toolbox::Pid > &pid_vector)
Initialize a PID controller and add it to vector of controllers.
Definition: pose_tracking.cpp:200


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