katana_gripper_joint_trajectory_controller.cpp
Go to the documentation of this file.
1 /*
2  * UOS-ROS packages - Robot Operating System code by the University of Osnabrück
3  * Copyright (C) 2011 University of Osnabrück
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * katana_gripper_joint_trajectory_controller.h
20  *
21  * Created on: 20.10.2011
22  * Author: Karl Glatz <glatz@hs-weingarten.de>
23  * Ravensburg-Weingarten, University of Applied Sciences
24  *
25  * based on joint_trajectory_action/src/joint_trajectory_action.cpp
26  *
27  */
28 
30 
31 namespace katana_gazebo_plugins
32 {
33 
35  has_active_goal_(false), trajectory_finished_(true) /* c++0x: , current_point_({0.0, 0.0}), last_desired_point_( {0.0, 0.0})*/
36 {
37 
38  GRKAPoint default_point = {0.0, 0.0};
39  current_point_ = default_point;
40  last_desired_point_ = default_point;
41 
42  // set the joints fixed here
43  joint_names_.push_back((std::string)"katana_r_finger_joint");
44  joint_names_.push_back((std::string)"katana_l_finger_joint");
45 
46  pn.param("constraints/goal_time", goal_time_constraint_, 5.0);
47 
48  // Gets the constraints for each joint.
49  for (size_t i = 0; i < joint_names_.size(); ++i)
50  {
51  std::string ns = std::string("constraints/") + joint_names_[i];
52  double g, t;
53  pn.param(ns + "/goal", g, -1.0);
54  pn.param(ns + "/trajectory", t, -1.0);
56  trajectory_constraints_[joint_names_[i]] = t;
57  }
58  pn.param("constraints/stopped_velocity_tolerance", stopped_velocity_tolerance_, 0.01);
59 
60  ros::NodeHandle action_node("katana_arm_controller");
61 
62  action_server_ = new JTAS(action_node, "gripper_joint_trajectory_action",
63  boost::bind(&KatanaGripperJointTrajectoryController::goalCB, this, _1),
64  boost::bind(&KatanaGripperJointTrajectoryController::cancelCB, this, _1), false);
65 
67  ROS_INFO(
68  "katana gripper joint trajectory action server started on topic katana_arm_controller/gripper_joint_trajectory_action");
69 
70 }
71 
73 {
74  delete action_server_;
75 }
76 
77 bool KatanaGripperJointTrajectoryController::setsEqual(const std::vector<std::string> &a,
78  const std::vector<std::string> &b)
79 {
80  if (a.size() != b.size())
81  return false;
82 
83  for (size_t i = 0; i < a.size(); ++i)
84  {
85  if (count(b.begin(), b.end(), a[i]) != 1)
86  return false;
87  }
88  for (size_t i = 0; i < b.size(); ++i)
89  {
90  if (count(a.begin(), a.end(), b[i]) != 1)
91  return false;
92  }
93 
94  return true;
95 }
96 
98 {
99 
100  ros::Time now = ros::Time::now();
101 
102  if (!has_active_goal_)
103  return;
104  if (current_traj_.points.empty())
105  return;
106 
107  // time left?
108  if (now < current_traj_.header.stamp + current_traj_.points[0].time_from_start)
109  return;
110 
111  int last = current_traj_.points.size() - 1;
112  ros::Time end_time = current_traj_.header.stamp + current_traj_.points[last].time_from_start;
113 
114  bool inside_goal_constraints = false;
115 
116  if (this->isTrajectoryFinished())
117  {
118 
119  if (this->currentIsDesiredAngle())
120  {
121  inside_goal_constraints = true;
122  }
123 
124  }
125 
126  if (inside_goal_constraints)
127  {
128  ROS_DEBUG("Goal Succeeded!");
130  has_active_goal_ = false;
131  ROS_INFO("last_desired_point_.position: %f current_point_.position: %f", last_desired_point_.position, current_point_.position);
132  }
133  else if (now < end_time + ros::Duration(goal_time_constraint_))
134  {
135  // Still have some time left to make it.
136  ROS_DEBUG("Still have some time left to make it.");
137  //ROS_INFO("Still have some time left to make it. current_point_.position: %f ", current_point_.position);
138  }
139  else
140  {
141  ROS_WARN(
142  "Aborting because we wound up outside the goal constraints [current_angle: %f last_desired_angle: %f ]", current_point_.position, last_desired_point_.position);
144  has_active_goal_ = false;
145  }
146 
147 }
148 
150 {
151 
152  double current_angle_ = current_point_.position;
153  double desired_angle_ = last_desired_point_.position;
154 
155  ROS_DEBUG("current_angle_: %f desired_angle_: %f", current_angle_, desired_angle_);
156 
157  return ((current_angle_ - GRIPPER_ANGLE_THRESHOLD) <= desired_angle_
158  && (current_angle_ + GRIPPER_ANGLE_THRESHOLD) >= desired_angle_);
159 
160 }
161 
163 {
164 
165  ROS_DEBUG("KatanaGripperJointTrajectoryController::goalCB");
166 
167  // Ensures that the joints in the goal match the joints we are commanding.
168  if (!setsEqual(joint_names_, gh.getGoal()->trajectory.joint_names))
169  {
170  ROS_ERROR("KatanaGripperJointTrajectoryController::goalCB: Joints on incoming goal don't match our joints");
171  gh.setRejected();
172  return;
173  }
174 
175  double desired_start_pos = gh.getGoal()->trajectory.points[0].positions[0];
176  if (fabs(desired_start_pos - current_point_.position) > 0.05) {
177  ROS_ERROR("Input trajectory is invalid (difference between desired and current point too high: %f). This might crash Gazebo with error \"The minimum corner of the box must be less than or equal to maximum corner\".", fabs(desired_start_pos - current_point_.position));
178  gh.setRejected();
179  return;
180  }
181 
182  // Cancels the currently active goal.
183  if (has_active_goal_)
184  {
185  // Stops the controller.
186  trajectory_finished_ = true;
187 
188  // Marks the current goal as canceled.
190  has_active_goal_ = false;
191  }
192 
193  gh.setAccepted();
194  active_goal_ = gh;
195  has_active_goal_ = true;
196 
197  // Sends the trajectory "along to the controller"
198  this->setCurrentTrajectory(active_goal_.getGoal()->trajectory);
199 }
200 
202 {
203  if (active_goal_ == gh)
204  {
205  // stop sending points
206  trajectory_finished_ = true;
207 
208  // Marks the current goal as canceled.
210  has_active_goal_ = false;
211  }
212 }
213 
214 void KatanaGripperJointTrajectoryController::setCurrentTrajectory(trajectory_msgs::JointTrajectory traj)
215 {
216 
217  if (traj.points.empty())
218  {
219  ROS_WARN("KatanaGripperJointTrajectoryController::setCurrentTrajectory: Empty trajectory");
220  return;
221  }
222 
223  //TODO: check current position of the gripper to avoid too big efforts
224 
225  // traj.points.resize(traj.points.size()+1);
226 
227 
228  this->current_traj_ = traj;
229  // set the finished flag to false for this new trajectory
230  this->trajectory_finished_ = false;
231 
232 }
233 
235 {
236  //ROS_INFO("getNextDesiredPoint");
237 
238  trajectory_msgs::JointTrajectory traj = current_traj_;
239 
240  // is there a active trajectory?
242  {
243  // just send the last point (default 0.0)
244  return current_point_;
245  }
246 
247  // should we start already??
248  if (time.toSec() < traj.header.stamp.toSec())
249  {
250  // just send the last point (default 0.0)
251  return current_point_;
252  }
253 
254  ros::Duration relative_time = ros::Duration(time.toSec() - traj.header.stamp.toSec());
255 
256  //ROS_INFO("time: %f | header.stamp %f", time.toSec(), traj.header.stamp.toSec());
257  //ROS_INFO("relative_time %f", relative_time.toSec());
258 
259  // search for correct trajectory segment
260  size_t traj_segment = 0;
261  bool found_traj_seg = false;
262  size_t numof_points = traj.points.size();
263  for (size_t i = 1; i < numof_points; i++)
264  {
265  if (traj.points[i].time_from_start >= relative_time)
266  {
267  traj_segment = i;
268  found_traj_seg = true;
269  break;
270  }
271  }
272 
273  // segment found?
274  // not found happens only if the time is beyond of any time_from_start values of the points in the trajectory
275  if (!found_traj_seg)
276  {
277  ROS_INFO(
278  "Trajectory finished (requested time %f time_from_start[last_point]: %f)", relative_time.toSec(), traj.points[traj.points.size()-1].time_from_start.toSec());
279 
280  // set trajectory to finished
281  trajectory_finished_ = true;
282 
283  // stay at the last point
284  return last_desired_point_;
285  }
286 
287  // sample one point at current time
288  size_t start_index = traj_segment - 1;
289  size_t end_index = traj_segment;
290 
291  double start_pos = traj.points[start_index].positions[0];
292  double start_vel = traj.points[start_index].velocities[0];
293 // double start_acc = traj.points[start_index].accelerations[0];
294 
295  //ROS_INFO("start_index %i: start_pos %f start_vel %f", start_index, start_pos, start_vel);
296 
297  double end_pos = traj.points[end_index].positions[0];
298  double end_vel = traj.points[end_index].velocities[0];
299 // double end_acc = traj.points[end_index].accelerations[0];
300 
301  //ROS_INFO("end_index %i: end_pos %f end_vel %f", end_index, end_pos, end_vel);
302 
303  double time_from_start = traj.points[end_index].time_from_start.toSec();
304 // double duration = traj.points[end_index].time_from_start.toSec() - traj.points[start_index].time_from_start.toSec();
305 
306  //ROS_INFO("time_from_start %f | relative_time.toSec() %f", time_from_start, relative_time.toSec());
307 
308  //TODO: save the coefficients for each segment
309  std::vector<double> coefficients;
310 
311  spline_smoother::getCubicSplineCoefficients(start_pos, start_vel, end_pos, end_vel, time_from_start, coefficients);
312 
313  double sample_pos = 0, sample_vel = 0, sample_acc = 0;
314 // katana::sampleSplineWithTimeBounds(coefficients, duration, relative_time.toSec(), sample_pos, sample_vel, sample_acc);
315  spline_smoother::sampleCubicSpline(coefficients, relative_time.toSec(), sample_pos, sample_vel, sample_acc);
316 
317  //ROS_INFO("sample_pos: %f, sample_vel: %f", sample_pos, sample_vel);
318  //ROS_INFO("current_point_.position: %f ", current_point_.position);
319 
320  GRKAPoint point = {sample_pos, sample_vel};
321 
322  // set the last desired point
323  last_desired_point_ = point;
324 
325  return point;
326 
327 }
328 
330 {
331  return trajectory_finished_;
332 }
333 
334 
335 void KatanaGripperJointTrajectoryController::getGains(double &p, double &i, double &d, double &i_max, double &i_min) {
336  p = 6.0;
337  i = 0.1;
338  d = 0.1;
339 }
340 
341 
342 } // end namespace
343 
void setRejected(const Result &result=Result(), const std::string &text=std::string(""))
boost::shared_ptr< const Goal > getGoal() const
actionlib::ActionServer< control_msgs::JointTrajectoryAction > JTAS
#define ROS_WARN(...)
void setCanceled(const Result &result=Result(), const std::string &text=std::string(""))
void setAccepted(const std::string &text=std::string(""))
void getCubicSplineCoefficients(double start_pos, double start_vel, double end_pos, double end_vel, double time, std::vector< double > &coefficients)
Calculates cubic spline coefficients given the start and end way-points.
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void sampleCubicSpline(const std::vector< double > &coefficients, double time, double &position, double &velocity, double &acceleration)
Samples a cubic spline segment at a particular time.
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
void getGains(double &p, double &i, double &d, double &i_max, double &i_min)
static Time now()
#define ROS_ERROR(...)
static bool setsEqual(const std::vector< std::string > &a, const std::vector< std::string > &b)
#define ROS_DEBUG(...)


katana_gazebo_plugins
Author(s): Martin Günther
autogenerated on Fri Jan 3 2020 04:01:10