simple_resample_filter.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2013, Southwest Research Institute
5  * Copyright (C) 2019, FUJISOFT
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions 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 copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * * Neither the name of the Southwest Research Institute, nor the names
17  * of its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 #include <ros/ros.h>
35 
36 using namespace fsrobo_r_trajectory_filters;
37 
38 const double DEFAULT_SAMPLE_DURATION = 0.050; //seconds
39 
40 template<typename T>
43  {
44  ROS_INFO_STREAM("Constructing N point filter");
46  this->filter_name_ = "UniformSampleFilter";
47  this->filter_type_ = "UniformSampleFilter";
48  }
49 
50 template<typename T>
52  {
53  }
54 
55 template<typename T>
57  {
58  if (!this->nh_.getParam("sample_duration", sample_duration_))
59  {
60  ROS_WARN_STREAM( "UniformSampleFilter, params has no attribute sample_duration.");
61  }
62  ROS_INFO_STREAM("Using a sample_duration value of " << sample_duration_);
63 
64  return true;
65  }
66 
67 template<typename T>
68  bool SimpleResampleFilter<T>::update(const T& trajectory_in, T& trajectory_out)
69  {
70  bool success = false;
71  size_t size_in = trajectory_in.request.trajectory.points.size();
72  double duration_in = trajectory_in.request.trajectory.points.back().time_from_start.toSec();
73  double interpolated_time = 0.0;
74  size_t index_in = 0;
75 
76  trajectory_msgs::JointTrajectoryPoint p1, p2, interp_pt;
77 
78  trajectory_out = trajectory_in;
79 
80  // Clear out the trajectory points
81  trajectory_out.request.trajectory.points.clear();
82 
83  while (interpolated_time < duration_in)
84  {
85  ROS_DEBUG_STREAM("Interpolated time: " << interpolated_time);
86  // Increment index until the interpolated time is past the start time.
87  while (interpolated_time > trajectory_in.request.trajectory.points[index_in + 1].time_from_start.toSec())
88  {
90  "Interpolated time: " << interpolated_time << ", next point time: " << (trajectory_in.request.trajectory.points[index_in + 1].time_from_start.toSec()));
91  ROS_DEBUG_STREAM("Incrementing index");
92  index_in++;
93  if (index_in >= size_in)
94  {
96  "Programming error, index: " << index_in << ", greater(or equal) to size: " << size_in << " input duration: " << duration_in << " interpolated time:)" << interpolated_time);
97  return false;
98  }
99  }
100  p1 = trajectory_in.request.trajectory.points[index_in];
101  p2 = trajectory_in.request.trajectory.points[index_in + 1];
102  if (!interpolatePt(p1, p2, interpolated_time, interp_pt))
103  {
104  ROS_ERROR_STREAM("Failed to interpolate point");
105  return false;
106  }
107  trajectory_out.request.trajectory.points.push_back(interp_pt);
108  //trajectory_out.request.trajectory.points.push_back(p1);
109  interpolated_time += sample_duration_;
110 
111  }
112 
114  "Interpolated time exceeds original trajectory (quitting), original: " << duration_in << " final interpolated time: " << interpolated_time);
115  p2 = trajectory_in.request.trajectory.points.back();
116  p2.time_from_start = ros::Duration(interpolated_time);
117  // TODO: Really should check that appending the last point doesn't result in
118  // really slow motion at the end. This could happen if the sample duration is a
119  // large percentage of the trajectory duration (not likely).
120  trajectory_out.request.trajectory.points.push_back(p2);
121 
123  "Uniform sampling, resample duraction: " << sample_duration_ << " input traj. size: " << trajectory_in.request.trajectory.points.size() << " output traj. size: " << trajectory_out.request.trajectory.points.size());
124 
125  success = true;
126  return success;
127  }
128 template<typename T>
129  bool SimpleResampleFilter<T>::interpolatePt(trajectory_msgs::JointTrajectoryPoint & p1,
130  trajectory_msgs::JointTrajectoryPoint & p2, double time_from_start,
131  trajectory_msgs::JointTrajectoryPoint & interp_pt)
132  {
133  bool rtn = false;
134  double p1_time_from_start = p1.time_from_start.toSec();
135  double p2_time_from_start = p2.time_from_start.toSec();
136 
137  ROS_DEBUG_STREAM("time from start: " << time_from_start);
138 
139  if (time_from_start >= p1_time_from_start && time_from_start <= p2_time_from_start)
140  {
141  if (p1.positions.size() == p1.velocities.size() && p1.positions.size() == p1.accelerations.size())
142  {
143  if (p1.positions.size() == p2.positions.size() && p1.velocities.size() == p2.velocities.size()
144  && p1.accelerations.size() == p2.accelerations.size())
145  {
146  // Copy p1 to ensure the interp_pt has the correct size vectors
147  interp_pt = p1;
148  ROS_DEBUG_STREAM( "---------------Begin interpolating joint point---------------");
149 
150  for (size_t i = 0; i < p1.positions.size(); ++i)
151  {
152  double time_from_p1 = time_from_start - p1.time_from_start.toSec();
153  double time_from_p1_to_p2 = p2_time_from_start - p1_time_from_start;
154 
155  ROS_DEBUG_STREAM("time from p1: " << time_from_p1);
156  ROS_DEBUG_STREAM( "time_from_p1_to_p2: " << time_from_p1_to_p2);
157 
158  ros::Duration time_from_start_dur(time_from_start);
159  ROS_DEBUG_STREAM( "time from start_dur: " << time_from_start_dur);
160 
161  interp_pt.time_from_start = time_from_start_dur;
162  interp_pt.velocities[i] = p1.velocities[i] + (p2.velocities[i] - p1.velocities[i]) / time_from_p1_to_p2 * time_from_p1;
163  double acc = (p2.velocities[i] - p1.velocities[i]) / time_from_p1_to_p2;
164  interp_pt.positions[i] = p1.positions[i] + p1.velocities[i] * time_from_p1 + acc * time_from_p1 * time_from_p1 / 2.0;
165  interp_pt.accelerations[i] = p1.accelerations[i];
166 
168  "p1.pos: " << p1.positions[i] << ", vel: " << p1.velocities[i] << ", acc: " << p1.accelerations[i] << ", tfs: " << p1.time_from_start);
169 
171  "p2.pos: " << p2.positions[i] << ", vel: " << p2.velocities[i] << ", acc: " << p2.accelerations[i] << ", tfs: " << p2.time_from_start);
172 
174  "interp_pt.pos: " << interp_pt.positions[i] << ", vel: " << interp_pt.velocities[i] << ", acc: " << interp_pt.accelerations[i] << ", tfs: " << interp_pt.time_from_start);
175  }
176  ROS_DEBUG_STREAM( "---------------End interpolating joint point---------------");
177  rtn = true;
178  }
179  else
180  {
181  ROS_ERROR_STREAM("Trajectory point size mismatch");
183  "Trajectory point 1, pos: " << p1.positions.size() << " vel: " << p1.velocities.size() << " acc: " << p1.accelerations.size());
185  "Trajectory point 2, pos: " << p2.positions.size() << " vel: " << p2.velocities.size() << " acc: " << p2.accelerations.size());
186  rtn = false;
187  }
188 
189  }
190  else
191  {
193  "Trajectory point not fully defined, pos: " << p1.positions.size() << " vel: " << p1.velocities.size() << " acc: " << p1.accelerations.size());
194  rtn = false;
195  }
196  }
197  else
198  {
200  "Time: " << time_from_start << " not between interpolation point times[" << p1.time_from_start.toSec() << "," << p2.time_from_start.toSec() << "]");
201  rtn = false;
202  }
203 
204  return rtn;
205  }
206 
207 // registering planner adapter
bool update(const T &trajectory_in, T &trajectory_out)
ros::NodeHandle nh_
Internal node handle (used for parameter lookup)
Definition: filter_base.h:203
std::string filter_name_
filter name
Definition: filter_base.h:188
CLASS_LOADER_REGISTER_CLASS(fsrobo_r_trajectory_filters::SimpleResampleFilterAdapter, planning_request_adapter::PlanningRequestAdapter)
double sample_duration_
uniform sample duration (sec)
This version of the FilterBase<T> can be used to encapsulate the functionality from an arm navigation...
Definition: filter_base.h:124
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
virtual bool configure()
FilterBase method for the sub class to configure the filter This function must be implemented in the ...
This is a simple filter which performs a uniforming sampling of a trajectory using linear interpolati...
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
bool interpolatePt(trajectory_msgs::JointTrajectoryPoint &p1, trajectory_msgs::JointTrajectoryPoint &p2, double time_from_start, trajectory_msgs::JointTrajectoryPoint &interp_pt)
Perform interpolation between p1 and p2. Time from start must be in between p1 and p2 times...
const double DEFAULT_SAMPLE_DURATION
#define ROS_ERROR_STREAM(args)


fsrobo_r_trajectory_filters
Author(s): F-ROSROBO
autogenerated on Sun Feb 9 2020 03:58:38