uniform_sample_filter.cpp
Go to the documentation of this file.
00001 /*
00002 * Software License Agreement (BSD License)
00003 *
00004 * Copyright (c) 2013, Southwest Research Institute
00005 * All rights reserved.
00006 *
00007 * Redistribution and use in source and binary forms, with or without
00008 * modification, are permitted provided that the following conditions are met:
00009 *
00010 *       * Redistributions of source code must retain the above copyright
00011 *       notice, this list of conditions and the following disclaimer.
00012 *       * Redistributions in binary form must reproduce the above copyright
00013 *       notice, this list of conditions and the following disclaimer in the
00014 *       documentation and/or other materials provided with the distribution.
00015 *       * Neither the name of the Southwest Research Institute, nor the names
00016 *       of its contributors may be used to endorse or promote products derived
00017 *       from this software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 * POSSIBILITY OF SUCH DAMAGE.
00030 */
00031 
00032 #include <arm_navigation_msgs/FilterJointTrajectoryWithConstraints.h>
00033 #include <industrial_trajectory_filters/uniform_sample_filter.h>
00034 
00035 #include <kdl/velocityprofile_spline.hpp>
00036 #include <ros/ros.h>
00037 
00038 using namespace industrial_trajectory_filters;
00039 
00040 const double DEFAULT_SAMPLE_DURATION=0.050;  //seconds
00041 
00042 
00043 template <typename T>
00044 UniformSampleFilter<T>::UniformSampleFilter()
00045 {
00046         ROS_INFO_STREAM("Constructing N point filter");
00047         sample_duration_ = DEFAULT_SAMPLE_DURATION;
00048 }
00049 
00050 template <typename T>
00051 UniformSampleFilter<T>::~UniformSampleFilter()
00052 {}
00053 
00054 template <typename T>
00055 bool UniformSampleFilter<T>::configure()
00056 {
00057   if (!filters::FilterBase<T>::getParam("sample_duration", sample_duration_))
00058   {
00059     ROS_WARN_STREAM("UniformSampleFilter, params has no attribute sample_duration.");
00060   }
00061   ROS_INFO_STREAM("Using a sample_duration value of " << sample_duration_);
00062 
00063  return true;
00064 }
00065 
00066 
00067 template <typename T>
00068 bool UniformSampleFilter<T>::update(const T& trajectory_in,
00069                                    T& trajectory_out)
00070 {
00071   bool success = false;
00072   size_t size_in = trajectory_in.request.trajectory.points.size();
00073   double duration_in = trajectory_in.request.trajectory.points.back().time_from_start.toSec();
00074   double interpolated_time = 0.0;
00075   size_t index_in = 0;
00076 
00077   trajectory_msgs::JointTrajectoryPoint p1, p2, interp_pt;
00078 
00079   trajectory_out = trajectory_in;
00080 
00081   // Clear out the trajectory points
00082   trajectory_out.request.trajectory.points.clear();
00083 
00084   while(interpolated_time < duration_in)
00085   {
00086           ROS_INFO_STREAM("Interpolated time: " << interpolated_time);
00087           // Increment index until the interpolated time is past the start time.
00088           while(interpolated_time > trajectory_in.request.trajectory.points[index_in + 1].time_from_start.toSec())
00089           {
00090                   ROS_INFO_STREAM("Interpolated time: " << interpolated_time << ", next point time: "
00091                                   << (trajectory_in.request.trajectory.points[index_in + 1].time_from_start.toSec()) );
00092                   ROS_INFO_STREAM("Incrementing index");
00093                   index_in++;
00094                   if(index_in >= size_in)
00095                   {
00096                           ROS_ERROR_STREAM("Programming error, index: " << index_in << ", greater(or equal) to size: "
00097                                           << size_in << " input duration: " << duration_in << " interpolated time:)"
00098                                           << interpolated_time);
00099                           return false;
00100                   }
00101           }
00102           p1 = trajectory_in.request.trajectory.points[index_in];
00103           p2 = trajectory_in.request.trajectory.points[index_in + 1];
00104           if( !interpolatePt(p1, p2, interpolated_time, interp_pt))
00105           {
00106                   ROS_ERROR_STREAM("Failed to interpolate point");
00107                   return false;
00108           }
00109           trajectory_out.request.trajectory.points.push_back(interp_pt);
00110           interpolated_time += sample_duration_;
00111 
00112   }
00113 
00114         ROS_INFO_STREAM("Interpolated time exceeds original trajectory (quitting), original: " <<
00115                         duration_in << " final interpolated time: " << interpolated_time );
00116         p2 = trajectory_in.request.trajectory.points.back();
00117         p2.time_from_start = ros::Duration(interpolated_time);
00118         // TODO: Really should check that appending the last point doesn't result in
00119         // really slow motion at the end.  This could happen if the sample duration is a
00120         // large percentage of the trajectory duration (not likely).
00121         trajectory_out.request.trajectory.points.push_back(p2);
00122 
00123         ROS_INFO_STREAM("Uniform sampling, resample duraction: " << sample_duration_
00124                         << " input traj. size: " << trajectory_in.request.trajectory.points.size()
00125                         << " output traj. size: " << trajectory_out.request.trajectory.points.size());
00126 
00127         success = true;
00128         return success;
00129 }
00130 
00131 template <typename T>
00132 bool UniformSampleFilter<T>::interpolatePt(
00133                 trajectory_msgs::JointTrajectoryPoint & p1,
00134                 trajectory_msgs::JointTrajectoryPoint & p2,
00135                 double time_from_start, trajectory_msgs::JointTrajectoryPoint & interp_pt)
00136         {
00137                 bool rtn = false;
00138                 double p1_time_from_start = p1.time_from_start.toSec();
00139                 double p2_time_from_start = p2.time_from_start.toSec();
00140 
00141                 ROS_INFO_STREAM("time from start: " << time_from_start);
00142 
00143                 if (time_from_start >= p1_time_from_start && time_from_start <= p2_time_from_start)
00144                 {
00145                         if (p1.positions.size() == p1.velocities.size() &&
00146                                         p1.positions.size() == p1.accelerations.size())
00147                         {
00148                                 if( p1.positions.size() == p2.positions.size() &&
00149                                                 p1.velocities.size() == p2.velocities.size() &&
00150                                                 p1.accelerations.size() == p2.accelerations.size() )
00151                                 {
00152                                         // Copy p1 to ensure the interp_pt has the correct size vectors
00153                                         interp_pt = p1;
00154                                         // TODO: Creating a new spline calculator in this function means that
00155                                         // it may be created multiple times for the same points (assuming the
00156                                         // resample duration is less that the actual duration, which it might
00157                                         // be sometimes)
00158                                         KDL::VelocityProfile_Spline spline_calc;
00159                                         ROS_INFO_STREAM("---------------Begin interpolating joint point---------------");
00160 
00161                                         for( size_t i = 0; i < p1.positions.size(); ++i )
00162                                         {
00163                                                 // Calculated relative times for spline calculation
00164                                                 double time_from_p1 = time_from_start - p1.time_from_start.toSec();
00165                                                 double time_from_p1_to_p2 = p2_time_from_start - p1_time_from_start;
00166 
00167                                                 ROS_INFO_STREAM("time from p1: " << time_from_p1);
00168                                                 ROS_INFO_STREAM("time_from_p1_to_p2: " << time_from_p1_to_p2);
00169 
00170                                                 spline_calc.SetProfileDuration(p1.positions[i], p1.velocities[i], p1.accelerations[i],
00171                                                                 p2.positions[i], p2.velocities[i], p2.accelerations[i],  time_from_p1_to_p2);
00172 
00173                                                 ros::Duration time_from_start_dur(time_from_start);
00174                                                 ROS_INFO_STREAM("time from start_dur: " << time_from_start_dur);
00175 
00176                                                 interp_pt.time_from_start = time_from_start_dur;
00177                                                 interp_pt.positions[i] = spline_calc.Pos(time_from_p1);
00178                                                 interp_pt.velocities[i] = spline_calc.Vel(time_from_p1);
00179                                                 interp_pt.accelerations[i] = spline_calc.Acc(time_from_p1);
00180 
00181                                                 ROS_INFO_STREAM("p1.pos: " << p1.positions[i]
00182                                                         << ", vel: " << p1.velocities[i]
00183                                                         << ", acc: " << p1.accelerations[i]
00184                                                         << ", tfs: " << p1.time_from_start);
00185 
00186                                                 ROS_INFO_STREAM("p2.pos: " << p2.positions[i]
00187                                                                 << ", vel: " << p2.velocities[i]
00188                                                                 << ", acc: " << p2.accelerations[i]
00189                                                                 << ", tfs: " << p2.time_from_start);
00190 
00191                                                 ROS_INFO_STREAM("interp_pt.pos: " << interp_pt.positions[i]
00192                                                                 << ", vel: " << interp_pt.velocities[i]
00193                                                                 << ", acc: " << interp_pt.accelerations[i]
00194                                                                 << ", tfs: " << interp_pt.time_from_start);
00195                                 }
00196                                         ROS_INFO_STREAM("---------------End interpolating joint point---------------");
00197                                         rtn = true;
00198                                 }
00199                                 else
00200                                 {
00201                                         ROS_ERROR_STREAM("Trajectory point size mismatch");
00202                                         ROS_ERROR_STREAM("Trajectory point 1, pos: " << p1.positions.size() <<
00203                                                                                 " vel: " << p1.velocities.size() << " acc: " << p1.accelerations.size());
00204                                         ROS_ERROR_STREAM("Trajectory point 2, pos: " << p2.positions.size() <<
00205                                                                                 " vel: " << p2.velocities.size() << " acc: " << p2.accelerations.size());
00206                                         rtn = false;
00207                                 }
00208 
00209                         }
00210                         else
00211                         {
00212                                 ROS_ERROR_STREAM("Trajectory point not fully defined, pos: " << p1.positions.size() <<
00213                                                 " vel: " << p1.velocities.size() << " acc: " << p1.accelerations.size());
00214                                 rtn = false;
00215                         }
00216                 }
00217                 else
00218                 {
00219                         ROS_ERROR_STREAM("Time: " << time_from_start << " not between interpolation point times[" <<
00220                                         p1.time_from_start.toSec() << "," << p2.time_from_start.toSec() << "]");
00221                         rtn = false;
00222                 }
00223 
00224                 return rtn;
00225     }
00226 
00227 
00228 
00229 PLUGINLIB_DECLARE_CLASS(industrial_trajectory_filters,
00230                 IndustrialUniformSampleFilterJointTrajectoryWithConstraints,
00231                 industrial_trajectory_filters::UniformSampleFilter<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>,
00232                 filters::FilterBase<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>);
00233 


industrial_trajectory_filters
Author(s): Shaun Edwards
autogenerated on Mon Oct 6 2014 00:58:45