Go to the documentation of this file.00001 #include <cob_trajectory_controller/RefValJS_PTP_Trajectory.h>
00002 #include <stdexcept>
00003 #include <algorithm>
00004 #include <vector>
00005
00006
00007
00008 const double RefValJS_PTP_Trajectory::weigths[] = { 1.5, 1.5, 1.0, 1.0, 0.8, 0.8, 0.7 };
00009
00010
00011 inline double sqr(double x)
00012 {
00013 return x*x;
00014 }
00015
00016 RefValJS_PTP_Trajectory::RefValJS_PTP_Trajectory(const trajectory_msgs::JointTrajectory& trajectory, double v_rad_s, double a_rad_s2, bool smooth)
00017 {
00018 m_trajectory = trajectory;
00019 m_length = 0;
00020 m_stepSize = 0.4;
00021
00022 m_length_parts.clear();
00023 m_s_parts.clear();
00024
00025 if ( m_trajectory.points.size() < 1 )
00026 {
00027 throw std::runtime_error("Tried to create reference values for empty trajectory!");
00028 }
00029
00030 std::vector<std::vector<double> > zwischenPunkte;
00031
00032 if (smooth == false)
00033 {
00034
00035
00036
00037 double between_stepsize = 0.1;
00038 for (unsigned int i=0; i < m_trajectory.points.size()-1; i++)
00039 {
00040 std::vector<double> direction;
00041 direction.resize( m_trajectory.points[i+1].positions.size());
00042 double len = 0;
00043 for(unsigned int j = 0; j < m_trajectory.points[i+1].positions.size(); j++)
00044 {
00045 direction.at(j) = m_trajectory.points[i+1].positions.at(j)-m_trajectory.points[i].positions.at(j);
00046 len += direction.at(j) * direction.at(j);
00047 }
00048 double dist = sqrt(len);
00049 int num_segs = ceil(dist/between_stepsize);
00050 zwischenPunkte.resize(num_segs);
00051 for (int j=0; j < num_segs; j++)
00052 {
00053 std::vector<double> betw_joint;
00054 betw_joint.resize(direction.size());
00055 for(unsigned int d=0; d < direction.size(); d++)
00056 {
00057 betw_joint.at(d) = m_trajectory.points[i].positions.at(d) + direction.at(d) * ( (double)j / (double)num_segs );
00058 }
00059 zwischenPunkte.at(j) = betw_joint;
00060 }
00061 }
00062 zwischenPunkte.push_back( m_trajectory.points.back().positions );
00063 } else
00064 {
00065 zwischenPunkte.resize(trajectory.points.size());
00066 for(unsigned int i = 0; i < trajectory.points.size(); i++)
00067 {
00068 zwischenPunkte.at(i) = trajectory.points.at(i).positions;
00069 }
00070 }
00071 ROS_INFO("Calculated %d zwischenPunkte", zwischenPunkte.size());
00072
00073 m_TrajectorySpline.setCtrlPoints(zwischenPunkte);
00074
00075
00076
00077 if ( m_TrajectorySpline.ipoWithConstSampleDist(m_stepSize, m_SplinePoints)==false )
00078 {
00079
00080
00081 throw std::runtime_error("Error in BSplineND::ipoWithConstSampleDist!");
00082 }
00083 m_SplinePoints = zwischenPunkte;
00084 ROS_INFO("Calculated %d splinepoints", m_SplinePoints.size());
00085
00086 m_length_cumulated.clear();
00087 m_length_cumulated.push_back(0.0);
00088
00089 for (unsigned int i=0; i < m_SplinePoints.size()-1; i++)
00090 {
00091 std::vector<double> dist;
00092 dist.resize(m_SplinePoints[i].size());
00093 for(unsigned int j=0; j < m_SplinePoints[i].size(); j++)
00094 {
00095 dist.at(j) = m_SplinePoints[i+1].at(j) - m_SplinePoints[i].at(j);
00096 }
00097
00098
00099 m_length_parts.push_back( norm(dist) );
00100 m_length += norm(dist);
00101 m_length_cumulated.push_back(m_length);
00102 }
00103
00104 m_param_length = m_TrajectorySpline.getMaxdPos();
00105
00106 for (unsigned int i=0; i < m_length_parts.size(); i++)
00107 {
00108 m_s_parts.push_back( m_length_parts[i] / m_length );
00109 }
00110
00111 m_v_rad_s = v_rad_s;
00112 m_a_rad_s2 = a_rad_s2;
00113
00114
00115 double a = fabs(m_a_rad_s2);
00116 double v = fabs(m_v_rad_s);
00117
00118 if (m_length > v*v/a)
00119 {
00120
00121 m_T1 = m_T3 = v / a;
00122 m_T2 = (m_length - v*v/a) / v;
00123
00124
00125 m_sv2 = 1.0 / (m_T1 + m_T2);
00126 m_sa1 = m_sv2 / m_T1;
00127 m_sa3 = -m_sa1;
00128 }
00129 else {
00130
00131 m_T2 = 0.0;
00132 m_T1 = m_T3 = sqrt(m_length / a);
00133
00134 m_sv2 = 1.0 / m_T1;
00135 m_sa1 = m_sv2 / m_T1;
00136 m_sa3 = -m_sa1;
00137
00138 }
00139
00140
00141 }
00142
00143 std::vector<double> RefValJS_PTP_Trajectory::r(double s) const
00144 {
00145
00146 std::vector<double> soll;
00147 if (s <= 0)
00148 {
00149 soll = m_trajectory.points.front().positions;
00150 } else
00151 if (s < 1)
00152 {
00153
00154
00155
00156
00157
00158
00159
00160
00161 vecd_it start = m_length_cumulated.begin();
00162 vecd_it end = m_length_cumulated.end();
00163 vecd_it it = upper_bound(start, end, s * m_length);
00164
00165 int i = int(it-start) - 1;
00166 double frac = (s * m_length - m_length_cumulated[i]) / m_length_parts[i];
00167
00168
00169
00170
00171
00172
00173
00174 soll.resize(m_SplinePoints[i].size());
00175 for(unsigned int j = 0; j < m_SplinePoints[i].size(); j++)
00176 {
00177 soll.at(j) = m_SplinePoints[i].at(j) + (m_SplinePoints[i+1].at(j)-m_SplinePoints[i].at(j))*frac;
00178 }
00179 }
00180 else
00181 {
00182 soll = m_trajectory.points.back().positions;
00183 }
00184 return soll;
00185 }
00186
00187 double RefValJS_PTP_Trajectory::s(double t) const
00188 {
00189 if (t >= m_T1 + m_T2 + m_T3)
00190 return 1.0;
00191 else if (t >= m_T1 + m_T2)
00192 {
00193 return 0.5*m_sa1*m_T1*m_T1 + m_sv2*m_T2 + m_sv2*(t-m_T1-m_T2) + 0.5*m_sa3*sqr(t-m_T1-m_T2);
00194 }
00195 else if (t >= m_T1)
00196 {
00197 return 0.5*m_sa1*m_T1*m_T1 + m_sv2*(t-m_T1);
00198 }
00199 else if (t > 0.0)
00200 {
00201 return 0.5*m_sa1*t*t;
00202 }
00203 else return 0.0;
00204 }
00205
00206 double RefValJS_PTP_Trajectory::ds_dt(double t) const
00207 {
00208 if (t >= m_T1 + m_T2 + m_T3)
00209 return 0.0;
00210 else if (t >= m_T1 + m_T2)
00211 {
00212 return m_sv2 + m_sa3*(t-m_T1-m_T2);
00213 }
00214 else if (t >= m_T1)
00215 {
00216 return m_sv2;
00217 }
00218 else if (t > 0.0)
00219 {
00220 return m_sa1*t;
00221 }
00222 else return 0.0;
00223 }
00224
00225
00226 std::vector<double> RefValJS_PTP_Trajectory::dr_ds(double s) const
00227 {
00228
00229 std::vector<double> result = m_trajectory.points.front().positions;
00230 if (s < 0.0 || s >= 1.0)
00231 {
00232 for(unsigned int j=0; j < result.size(); j++)
00233 result.at(j) = 0.0;
00234 }
00235 else
00236 {
00237
00238 vecd_it start = m_length_cumulated.begin();
00239 vecd_it end = m_length_cumulated.end();
00240 vecd_it it = upper_bound(start, end, s * m_length);
00241
00242 int i = int(it-start) - 1;
00243 double frac = (s * m_length - m_length_cumulated[i]) / m_length_parts[i];
00244
00245
00246
00247
00248
00249
00250
00251 std::vector<double> vi;
00252 std::vector<double> vii;
00253
00254 double step_s = m_stepSize / m_param_length;
00255
00256 if ( i == 0 )
00257 {
00258
00259 step_s = m_length_parts[0] / m_length;
00260 vi.resize(m_SplinePoints[i].size());
00261 for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
00262 {
00263 vi.at(k) = (m_SplinePoints[1].at(k) - m_SplinePoints[0].at(k)) / step_s;
00264 }
00265 vii = vi;
00266
00267
00268
00269 } else
00270 if ( i == (int) m_SplinePoints.size() - 2 )
00271 {
00272
00273
00274
00275
00276 step_s = (m_length_parts[i]) / m_length;
00277 vii.resize(m_SplinePoints[i].size());
00278 for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
00279 vii.at(k) = (m_SplinePoints[i+1].at(k) - m_SplinePoints[i].at(k)) / step_s;
00280 vi = vii;
00281 } else
00282 {
00283
00284 step_s = (m_length_parts[i]+m_length_parts[i-1]) / m_length;
00285 vi.resize(m_SplinePoints[i].size());
00286 for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
00287 vi.at(k) = (m_SplinePoints[i+1].at(k) - m_SplinePoints[i-1].at(k)) / step_s;
00288 step_s = (m_length_parts[i]+m_length_parts[i+1]) / m_length;
00289 vii.resize(m_SplinePoints[i].size());
00290 for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
00291 vii.at(k) = (m_SplinePoints[i+2].at(k) - m_SplinePoints[i].at(k)) / step_s;
00292 }
00293
00294
00295 result.resize(m_SplinePoints[i].size());
00296 for(unsigned int k = 0; k < m_SplinePoints[i].size(); k++)
00297 result.at(k) = vi.at(k) + (vii.at(k)-vi.at(k))*frac;
00298 }
00299
00300 return result;
00301 }
00302
00303
00304
00305