$search
00001 /*************************************************************************** 00002 tag: Erwin Aertbelien Mon May 10 19:10:36 CEST 2004 path_roundedcomposite.cxx 00003 00004 path_roundedcomposite.cxx - description 00005 ------------------- 00006 begin : Mon May 10 2004 00007 copyright : (C) 2004 Erwin Aertbelien 00008 email : erwin.aertbelien@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, * 00024 * Suite 330, Boston, MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 /***************************************************************************** 00028 * \author 00029 * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven 00030 * 00031 * \version 00032 * ORO_Geometry V0.2 00033 * 00034 * \par History 00035 * - $log$ 00036 * 00037 * \par Release 00038 * $Id: path_roundedcomposite.cpp,v 1.1.1.1.2.5 2003/07/24 13:26:15 psoetens Exp $ 00039 * $Name: $ 00040 ****************************************************************************/ 00041 00042 00043 #include "path_roundedcomposite.hpp" 00044 #include "path_line.hpp" 00045 #include "path_circle.hpp" 00046 #include "utilities/error.h" 00047 #include <memory> 00048 00049 00050 namespace KDL { 00051 00052 // private constructor, to keep the type when cloning a Path_RoundedComposite, such that getIdentifier keeps on returning 00053 // the correct value: 00054 Path_RoundedComposite::Path_RoundedComposite(Path_Composite* _comp, 00055 double _radius, double _eqradius, RotationalInterpolation* _orient, 00056 bool _aggregate,int _nrofpoints): 00057 comp(_comp), radius(_radius), eqradius(_eqradius), orient(_orient), aggregate(_aggregate), nrofpoints(_nrofpoints) { 00058 } 00059 00060 Path_RoundedComposite::Path_RoundedComposite(double _radius,double _eqradius,RotationalInterpolation* _orient, bool _aggregate) : 00061 comp( new Path_Composite()), radius(_radius),eqradius(_eqradius), orient(_orient), aggregate(_aggregate) 00062 { 00063 nrofpoints = 0; 00064 if (eqradius<=0) { 00065 throw Error_MotionPlanning_Not_Feasible(1); 00066 } 00067 } 00068 00069 void Path_RoundedComposite::Add(const Frame& F_base_point) { 00070 double eps = 1E-7; 00071 if (nrofpoints == 0) { 00072 F_base_start = F_base_point; 00073 } else if (nrofpoints == 1) { 00074 F_base_via = F_base_point; 00075 } else { 00076 // calculate rounded segment : line + circle, 00077 // determine the angle between the line segments : 00078 Vector ab = F_base_via.p - F_base_start.p; 00079 Vector bc = F_base_point.p - F_base_via.p; 00080 double abdist = ab.Norm(); 00081 double bcdist = bc.Norm(); 00082 if (abdist < eps) { 00083 throw Error_MotionPlanning_Not_Feasible(2); 00084 } 00085 if (bcdist < eps) { 00086 throw Error_MotionPlanning_Not_Feasible(3); 00087 } 00088 double alpha = acos(dot(ab, bc) / abdist / bcdist); 00089 if ((PI - alpha) < eps) { 00090 throw Error_MotionPlanning_Not_Feasible(4); 00091 } 00092 if (alpha < eps) { 00093 // no rounding is done in the case of parallel line segments 00094 comp->Add( 00095 new Path_Line(F_base_start, F_base_via, orient->Clone(), 00096 eqradius)); 00097 F_base_start = F_base_via; 00098 F_base_via = F_base_point; 00099 } else { 00100 double d = radius / tan((PI - alpha) / 2); // tan. is guaranteed not to return zero. 00101 if (d >= abdist) 00102 throw Error_MotionPlanning_Not_Feasible(5); 00103 00104 if (d >= bcdist) 00105 throw Error_MotionPlanning_Not_Feasible(6); 00106 00107 std::auto_ptr < Path 00108 > line1( 00109 new Path_Line(F_base_start, F_base_via, 00110 orient->Clone(), eqradius)); 00111 std::auto_ptr < Path 00112 > line2( 00113 new Path_Line(F_base_via, F_base_point, 00114 orient->Clone(), eqradius)); 00115 Frame F_base_circlestart = line1->Pos(line1->LengthToS(abdist - d)); 00116 Frame F_base_circleend = line2->Pos(line2->LengthToS(d)); 00117 // end of circle segment, beginning of next line 00118 Vector V_base_t = ab * (ab * bc); 00119 V_base_t.Normalize(); 00120 comp->Add( 00121 new Path_Line(F_base_start, F_base_circlestart, 00122 orient->Clone(), eqradius)); 00123 comp->Add( 00124 new Path_Circle(F_base_circlestart, 00125 F_base_circlestart.p - V_base_t * radius, 00126 F_base_circleend.p, F_base_circleend.M, alpha, 00127 orient->Clone(), eqradius)); 00128 // shift for next line 00129 F_base_start = F_base_circleend; // end of the circle segment 00130 F_base_via = F_base_point; 00131 } 00132 } 00133 00134 nrofpoints++; 00135 } 00136 00137 void Path_RoundedComposite::Finish() { 00138 if (nrofpoints >= 1) { 00139 comp->Add( 00140 new Path_Line(F_base_start, F_base_via, orient->Clone(), 00141 eqradius)); 00142 } 00143 } 00144 00145 double Path_RoundedComposite::LengthToS(double length) { 00146 return comp->LengthToS(length); 00147 } 00148 00149 00150 double Path_RoundedComposite::PathLength() { 00151 return comp->PathLength(); 00152 } 00153 00154 Frame Path_RoundedComposite::Pos(double s) const { 00155 return comp->Pos(s); 00156 } 00157 00158 Twist Path_RoundedComposite::Vel(double s, double sd) const { 00159 return comp->Vel(s, sd); 00160 } 00161 00162 Twist Path_RoundedComposite::Acc(double s, double sd, double sdd) const { 00163 return comp->Acc(s, sd, sdd); 00164 } 00165 00166 void Path_RoundedComposite::Write(std::ostream& os) { 00167 comp->Write(os); 00168 } 00169 00170 int Path_RoundedComposite::GetNrOfSegments() { 00171 return comp->GetNrOfSegments(); 00172 } 00173 00174 Path* Path_RoundedComposite::GetSegment(int i) { 00175 return comp->GetSegment(i); 00176 } 00177 00178 double Path_RoundedComposite::GetLengthToEndOfSegment(int i) { 00179 return comp->GetLengthToEndOfSegment(i); 00180 } 00181 00182 void Path_RoundedComposite::GetCurrentSegmentLocation(double s, 00183 int& segment_number, double& inner_s) { 00184 comp->GetCurrentSegmentLocation(s,segment_number,inner_s); 00185 } 00186 00187 00188 00189 Path_RoundedComposite::~Path_RoundedComposite() { 00190 if (aggregate) 00191 delete orient; 00192 delete comp; 00193 } 00194 00195 00196 Path* Path_RoundedComposite::Clone() { 00197 return new Path_RoundedComposite(static_cast<Path_Composite*>(comp->Clone()),radius,eqradius,orient->Clone(), true, nrofpoints); 00198 } 00199 00200 }