Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <katana_trajectory_filter/katana_trajectory_filter.h>
00026
00027 namespace katana_trajectory_filter
00028 {
00029
00031 static const size_t MAX_NUM_POINTS = 16;
00032
00041 static const size_t DELETE_CHUNK_SIZE = 10;
00042
00043 template<typename T>
00044 KatanaTrajectoryFilter<T>::KatanaTrajectoryFilter()
00045 {
00046 }
00047
00048 template<typename T>
00049 KatanaTrajectoryFilter<T>::~KatanaTrajectoryFilter()
00050 {
00051 }
00052
00053 template<typename T>
00054 bool KatanaTrajectoryFilter<T>::smooth(const T& trajectory_in, T& trajectory_out) const
00055 {
00056 size_t num_points = trajectory_in.request.trajectory.points.size();
00057 trajectory_out = trajectory_in;
00058
00059 if (!spline_smoother::checkTrajectoryConsistency(trajectory_out))
00060 return false;
00061
00062 if (num_points <= MAX_NUM_POINTS)
00063
00064 return true;
00065
00066 while (true)
00067 {
00068 const T trajectory_mid = trajectory_out;
00069
00070 size_t num_points_delete = num_points - MAX_NUM_POINTS;
00071
00072 if (num_points_delete > DELETE_CHUNK_SIZE)
00073 num_points_delete = DELETE_CHUNK_SIZE;
00074 else if (num_points_delete <= 0)
00075 break;
00076
00077 remove_smallest_segments(trajectory_mid, trajectory_out, num_points_delete);
00078 num_points = trajectory_out.request.trajectory.points.size();
00079 }
00080
00081
00082 for (size_t i = 0; i < trajectory_out.request.trajectory.points.size(); ++i)
00083 {
00084 trajectory_out.request.trajectory.points[i].velocities.resize(0);
00085 trajectory_out.request.trajectory.points[i].accelerations.resize(0);
00086 }
00087
00088 return true;
00089 }
00090
00091 template<typename T>
00092 void KatanaTrajectoryFilter<T>::remove_smallest_segments(const T& trajectory_in, T& trajectory_out,
00093 const size_t num_points_delete) const
00094 {
00095 size_t num_points = trajectory_in.request.trajectory.points.size();
00096 std::vector<std::pair<size_t, double> > segment_durations(num_points - 1);
00097
00098
00099 for (size_t i = 0; i < num_points - 1; ++i)
00100 {
00101 double duration = (trajectory_in.request.trajectory.points[i + 1].time_from_start
00102 - trajectory_in.request.trajectory.points[i].time_from_start).toSec();
00103
00104 segment_durations[i] = std::pair<size_t, double>(i, duration);
00105 }
00106
00107 for (size_t i = 0; i < segment_durations.size(); i++)
00108 ROS_DEBUG("segment_durations[%3zu] = <%3zu, %f>", i, segment_durations[i].first, segment_durations[i].second);
00109
00110
00111 std::vector<std::pair<size_t, double> > sorted_segment_durations = segment_durations;
00112 std::sort(sorted_segment_durations.begin(), sorted_segment_durations.end(), boost::bind(&std::pair<size_t, double>::second, _1)
00113 < boost::bind(&std::pair<size_t, double>::second, _2));
00114
00115 for (size_t i = 0; i < sorted_segment_durations.size(); i++)
00116 ROS_DEBUG("sorted_segment_durations[%3zu] = <%3zu, %f>", i, sorted_segment_durations[i].first, sorted_segment_durations[i].second);
00117
00118
00119 std::set<size_t> delete_set;
00120 for (size_t i = 0; i < num_points_delete; i++)
00121 {
00122 size_t point_to_delete = sorted_segment_durations[i].first;
00123 if (point_to_delete == 0)
00124 {
00125
00126 point_to_delete = 1;
00127 }
00128 else if (point_to_delete == num_points - 1)
00129 {
00130
00131 }
00132 else
00133 {
00134
00135 if (segment_durations[point_to_delete - 1] > segment_durations[point_to_delete + 1])
00136 point_to_delete++;
00137
00138
00139
00140 }
00141
00142 delete_set.insert(point_to_delete);
00143 }
00144
00145 for (std::set<size_t>::iterator it = delete_set.begin(); it != delete_set.end(); it++)
00146 ROS_DEBUG("delete set entry: %zu", *it);
00147
00148 trajectory_out.request.trajectory.points.resize(0);
00149 for (size_t i = 0; i < num_points; i++)
00150 {
00151 if (delete_set.find(i) == delete_set.end())
00152 {
00153
00154 trajectory_out.request.trajectory.points.push_back(trajectory_in.request.trajectory.points[i]);
00155 }
00156 }
00157 }
00158
00159 }
00160
00161
00162 PLUGINLIB_DECLARE_CLASS(katana_trajectory_filter, KatanaTrajectoryFilterFilterJointTrajectory, katana_trajectory_filter::KatanaTrajectoryFilter<arm_navigation_msgs::FilterJointTrajectory>, filters::FilterBase<arm_navigation_msgs::FilterJointTrajectory>)
00163 PLUGINLIB_DECLARE_CLASS(katana_trajectory_filter, KatanaTrajectoryFilterFilterJointTrajectoryWithConstraints, katana_trajectory_filter::KatanaTrajectoryFilter<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>, filters::FilterBase<arm_navigation_msgs::FilterJointTrajectoryWithConstraints>)