path_simulate.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007                                                    *
00003  *   Human Rezaijafari <H.Rezai@web.de>                                    *
00004  *   This file is part of the FreeCAD CAM development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include "PreCompiled.h"
00024 #include "path_simulate.h"
00025 
00026 #include <GeomAPI_ProjectPointOnCurve.hxx>
00027 
00028 #include <TColgp_Array1OfPnt.hxx>
00029 #include <Base/Exception.h>
00030 #include <Base/Builder3D.h>
00031 #include <GCPnts_AbscissaPoint.hxx>
00032 #include <Geom_BSplineCurve.hxx>
00033 
00034 #define curvTOL  30.0  // gibt maximalen Kr�mmungsradius an ab welchem eine Unterteilung der Kurve erfolgt
00035 #define TolDist  1.0   // entspricht der Samplingschrittweite der Kurvenpunkte f�r den Roboter-Output 
00036 
00037 /* Konstruktor mit zwei Bahnfolgen (master tool & supporting die) als Input */
00038 path_simulate::path_simulate(const std::vector<Handle_Geom_BSplineCurve> &BSplineTop,
00039                              const std::vector<Handle_Geom_BSplineCurve> &BSplineBottom,
00040                              struct CuttingToolsSettings& set)
00041         :m_BSplineTop(BSplineTop),m_BSplineBottom(BSplineBottom),m_set(set),
00042         m_t0(0.0),m_step(1e-3),m_clip(90000)
00043 {
00044         
00045         m_pretension = m_set.spring_pretension;
00046         m_blech          = m_set.sheet_thickness;
00047         m_amax           = m_set.max_Acc;
00048     m_vmax       = m_set.max_Vel;
00049     
00050         m_single = false;
00051    
00052         if(m_pretension > 0) beam = true;  // flag f�r "write_output_***" generierung
00053         else                     beam = false;
00054 
00055     //Initialize the Iterators
00056     m_it1 = m_BSplineTop.begin();
00057     m_it2 = m_BSplineBottom.begin();
00058 
00059     //Initalise some vars
00060     gp_Pnt p(0,0,0);
00061     gp_Pnt q(0,0,0);
00062 
00063     /*------------------------------Generate the first movement of the Master------------*/
00064 
00065     /* Fill p with the starting point of the first Master curve*/
00066     (*m_it1)->D0((*m_it1)->FirstParameter(),p);
00067 
00068     /* Set q to the initial-Z-level in the Simulation: 2mm + Master-Radius over the sheet which is located at Z=0 */
00069     q.SetZ(2.0 + set.master_radius);
00070         
00071         //First we clear the vectors
00072     m_StartPnts1.clear();
00073     m_StartPnts2.clear();
00074 
00075     //Now we insert the start points for the Master movement
00076     m_StartPnts1.push_back(q);
00077     m_StartPnts1.push_back(p);
00078 
00079         //Inserts the start parameter
00080     m_StartParam.push_back((*m_it1)->FirstParameter());
00081 
00082     /*Master finished here*/
00083 
00084     /*-----------------------------Generate the first movement for the Slave--------------*/
00085 
00086     /* Fill p with the starting point of the first Slave curve*/
00087     (*m_it2)->D0((*m_it2)->FirstParameter(),p);
00088 
00089     /* Set q to the initial-Z-level in the Simulation: -5mm - Slave-Radius-Spring-Pretensionbelow the sheet upper level which is located at Z=0 */
00090     q.SetZ(-5.0 - set.slave_radius - m_pretension);
00091 
00092     /*Now we insert the start points for the Slave movement*/
00093     m_StartPnts2.push_back(q);
00094     m_StartPnts2.push_back(p);
00095 
00096         //Inserts the start parameter
00097         m_StartParam.push_back((*m_it2)->FirstParameter());
00098 
00099     /*Slave finished here*/
00100 }
00101 
00102 path_simulate::~path_simulate()
00103 {
00104 }
00105 
00106 /*
00107 double path_simulate::GetLength(GeomAdaptor_Curve& curve, const Standard_Real startParameter,const Standard_Real endParameter)
00108 {
00109     Standard_Real firstParameter = curve.FirstParameter();
00110     Standard_Real lastParameter  = curve.LastParameter();
00111 
00112 
00113     Standard_Real sParam = Min(startParameter,endParameter);
00114     Standard_Real eParam = Max(startParameter,endParameter);
00115 
00116     //Standard_Real length = 0.0;
00117 
00118     if ( eParam > lastParameter )
00119     {
00120         //get the first part of the lenght
00121         Standard_Real l1 = GetLength(curve,firstParameter,eParam-lastParameter);
00122         Standard_Real l2 = GetLength(curve,sParam,lastParameter);
00123         return l1 + l2;
00124     }
00125     if ( sParam < firstParameter )
00126     {
00127         Standard_Real l1 = GetLength(curve,lastParameter-fabs(sParam),lastParameter);
00128         Standard_Real l2 = GetLength(curve,firstParameter,eParam);
00129         return l1 + l2;
00130     }
00131 
00132 
00133     return GCPnts_AbscissaPoint::Length(curve,sParam,eParam);   // genauigkeitssteuerung �ber parameter TOL nach eParam 
00134 }
00135 */
00136 
00137 /*
00138 double path_simulate::FindParamAt(GeomAdaptor_Curve& curve, double dist, double startParam)
00139 {
00140     double param;
00141 
00142     //compute the parameter of the next point
00143     GCPnts_AbscissaPoint absc(curve, dist, startParam);
00144     if ( absc.IsDone() )
00145     {
00146         //the parameter is computed
00147         param = absc.Parameter();
00148     }
00149 
00150     return param;
00151 }
00152 */
00153 
00154 /* Hier wird die absolute Geschwindigkeitsfunktion definiert und liefert die Geschwindigkeit zur Zeiteingabe <t>. 
00155 Die Funktion gliedert sich in drei Abschnitte mit den Parametergrenzen <m_t0>, <m_t1>, <m_t2>, <m_T> welche z.B.
00156 mittels path_simulate::ParameterCalculation() ermittelt werden kann. 
00157 Die Start- und Endgeschwindigkeit m�ssen vorher in <m_v[0]> und <m_v[2]> bestimmt werden.
00158 Die maximale Geschwindigkeit welche zwischen <m_t1> und <m_t2> erreicht werden soll, entspricht hier <m_v[1]> */
00159 double path_simulate::GetVelocity(double t)
00160 {
00161     double vel;
00162     double c[2];
00163 
00164     c[0] = m_a/2.0;
00165 
00166     if (t>=m_t0 && t<=m_t1)
00167     {
00168         if (t==m_t0 || (m_v[1] - m_v[0]) == 0.0)
00169         {
00170             vel = m_v[0];
00171         }
00172         else
00173         {
00174                         c[1] = PI*m_a / (m_v[1] - m_v[0]);
00175             vel = c[0]*(sin(c[1]*(t-m_t0) - PI)/c[1] + (t-m_t0)) + m_v[0];
00176         }
00177     }
00178     else if (t>m_t1  && t<=m_t2)
00179     {
00180         vel = m_v[1];
00181     }
00182     else if (t>m_t2 && t<=m_T)
00183     {
00184         if (t==m_T)
00185         {
00186             vel = m_v[1] - c[0]*(t-m_t2);
00187         }
00188         else
00189         {
00190                         c[1] = PI*m_a / (m_v[1] - m_v[2]);
00191             vel = m_v[1] - c[0]*(sin(c[1]*(t-m_t2) - PI)/c[1] + (t-m_t2));
00192         }
00193     }
00194     else
00195         throw Base::Exception("time input not inside [t0, T]");
00196 
00197     return vel;
00198 }
00199 
00200 /* Diese Funktion liefert den zur�ckgelegten Weg zur Zeiteingabe <t> und entspricht 
00201 dem Integral der Funktion GetVelocity(t)*/
00202 double path_simulate::GetDistance(double t)
00203 {
00204     double d;
00205     double c[2];
00206 
00207     c[0] = m_a/2.0;
00208 
00209     if (t>=m_t0 && t<m_t1)
00210     {
00211         c[1] = PI*m_a / (m_v[1] - m_v[0]);
00212 
00213                 if(t==m_t0){d = 0.0;}
00214                 else{       d = -(c[0]/pow(c[1],2.0))*cos(c[1]*(t-m_t0) - PI) + 
00215                                       c[0]*pow((t-m_t0),2.0)/2 - c[0]/(c[1]*c[1]) + 
00216                                                   m_v[0]*(t-m_t0);}
00217     }
00218     else if (t>=m_t1  && t<=m_t2)
00219     {
00220         d = c[0]*pow((m_t1-m_t0),2.0)/2 + 
00221                         m_v[0]*(m_t1-m_t0) + 
00222                         m_v[1]*(t-m_t1);
00223     }
00224     else if (t>m_t2 && t<=m_T)
00225     {
00226         c[1] = PI*m_a / (m_v[1] - m_v[2]);
00227 
00228         if (t==m_T)
00229         {
00230             d = m_v[0]*(m_t1-m_t0) + c[0]*pow((m_t1-m_t0),2.0)/2 +
00231                                 m_v[1]*(m_t2-m_t1) - c[0]*pow((t-m_t2),2.0)/2 + 
00232                                 m_v[1]*(t-m_t2);
00233         }
00234                 else
00235                 {
00236                         d =  m_v[0]*(m_t1-m_t0) + c[0]*pow((m_t1-m_t0),2.0)/2 +
00237                                  m_v[1]*(m_t2-m_t1) + (c[0]/pow(c[1],2.0))*cos(c[1]*(t-m_t2) - PI) - 
00238                                                        c[0]*pow((t-m_t2),2.0)/2 + 
00239                                                                            c[0]/pow(c[1],2.0) + 
00240                                                                            m_v[1]*(t-m_t2);
00241                 }
00242     }
00243     else
00244     {
00245         throw Base::Exception("time input not inside [t0,T]");
00246     }
00247 
00248     return d;
00249 }
00250 
00251 /*
00252 double path_simulate::GetWireLength(TopoDS_Wire &aWire)
00253 {
00254  GProp_GProps lProps;
00255  BRepGProp::LinearProperties(aWire,lProps);
00256  double length = lProps.Mass();
00257  return length;
00258 }
00259 */
00260 
00261 /*Parameterberechnung der Geschwindigkeitsfunktion f�r eine gerade Strecke der L�nge <S1>*/
00262 bool path_simulate::ParameterCalculation_Line(double S1)
00263 {
00264     if (S1 == 0.0)  // hier gibts nichts zu tun
00265     {
00266         m_T = m_t0;
00267         return true;
00268     }
00269 
00270         m_a = m_amax;
00271 
00272         m_v[0] = 0.0;                  // Startgeschwindigkeit wird auf Null gesetzt
00273         m_v[1] = sqrt(m_a*S1/2.0);     // Geschwindigkeit die notwendig ist damit der Weg <S1> zur Zeit <m_T> erreicht wird
00274         m_v[2] = 0.0;                  // Endgeschwindigkeit wird auf Null gesetzt
00275 
00276         while(m_v[1] > m_vmax)         // maximale Geschwindigkeit darf nicht �berschritten werden
00277         {
00278                 m_a /= 2;                  // Versuchs erneut mit halber Beschleunigung
00279                 m_v[1] = sqrt(m_a*S1/2.0); // Geschwindigkeit die notwendig ist damit der Weg <S1> zur Zeit <m_T> erreicht wird
00280         }
00281 
00282         // Jetzt lassen sich die Zeitgrenzen berechnen
00283     m_t1 = 2*m_v[1]/m_a + m_t0;
00284     m_t2 = m_t1;
00285     m_T = 2*m_t1 - m_t0;
00286 
00287     return true;
00288 }
00289 
00290 /*Parameterberechnung der Geschwindigkeitsfunktion (definiert in path_simulate::GetVelocity())
00291 f�r einen Kurvenabschnitt der L�nge <S1>. Aufruf muss stets vor der Funktion path_simulate::GetVelocity() erfolgen*/
00292 bool path_simulate::ParameterCalculation_Curve(double S1)
00293 {
00294         // Berechnung der Zeitgrenzen
00295     m_t1 = m_t0 + 2*(abs(m_v[1]-m_v[0]))/m_a;
00296     m_t2 = m_t1;
00297     m_T  = m_t1 + 2*(abs(m_v[1]-m_v[2]))/m_a;
00298 
00299     double tmp, v_tmp;
00300     tmp = GetDistance(m_T);  // liefert den Weg zur�ck, der unter den gegebenen Parametereinstellungen,
00301                                  // zum hoch- und runterbeschleunigen, midestens notwendig ist 
00302 
00303     if (tmp <= S1) // d.h. der Weg reicht aus
00304     {
00305         m_t2 = m_t1 + (S1 - tmp)/m_v[1];  // zwischen <m_t1> und <m_t2> wird die Kurve mit der konstanten 
00306                                                   // Geschwindigkeit <m_v[1]> durchlaufen
00307     }
00308     else // Weg reicht nicht aus -> Parameterkorrektur                            
00309     {
00310                 // Berechne Geschwindigkeit die mindestenns notwendig ist damit der Weg <S1> zur Zeit <m_T> erreicht wird 
00311         m_v[1] = sqrt((m_a*S1 + m_v[0]*m_v[0] + m_v[2]*m_v[2])/2.0);  
00312                 m_t1 = m_t0 + 2*(abs(m_v[1]-m_v[0]))/m_a;
00313         m_t2 = m_t1;
00314                 
00315                 // hier wird evtl. eine Korrektur notwendig
00316                 if(m_v[1] > m_vmax)
00317                 {
00318                         m_v[1] = m_vmax;
00319                         
00320                         // ab hier wieder analog zu oben
00321                         m_t1 = m_t0 + 2*(abs(m_v[1]-m_v[0]))/m_a;
00322                         m_t2 = m_t1;
00323                         m_T  = m_t1 + 2*(abs(m_v[1]-m_v[2]))/m_a;
00324 
00325                         tmp = GetDistance(m_T);
00326 
00327                         if (tmp <= S1)
00328                         {
00329                                 m_t2 = m_t1 + (S1 - tmp)/m_v[1];
00330                         }
00331                         else
00332                         {
00333                                 v_tmp = (m_vmax - std::min(m_v[1],m_v[2]))/2.0;
00334                                 
00335                                 while(tmp > S1) // hier wird die Geschwindigkeit <m_v[1]> solange in Richtung <m_v[2]> vekleinert bis
00336                                                     // der Weg schlie�lich ausreicht
00337                                 {
00338                                         m_v[1] = std::min(m_v[1],m_v[2]) + v_tmp;
00339                         
00340                                         m_t1 = m_t0 + 2*(abs(m_v[1]-m_v[0]))/m_a;
00341                                     m_t2 = m_t1;
00342                                     m_T  = m_t1 + 2*(abs(m_v[1]-m_v[2]))/m_a;
00343 
00344                                     tmp = GetDistance(m_T);
00345                                 
00346                                         v_tmp /= 2.0;
00347                                 }
00348                         }
00349                 }
00350     }
00351 
00352     m_T = m_t2 + 2*(abs(m_v[1]-m_v[2]))/m_a;  // Endzeit l�sst sich jetzt berechnen
00353 
00354     return true;
00355 }
00356 
00357 /* setzt die Outputvektoren und den Beschleunigungsparameter <m_a> zur�ck. Die Startzeit <m_t0> wird aktualisiert*/
00358 bool path_simulate::UpdateParam()
00359 {
00360     m_Output.clear();
00361         m_Output2.clear();
00362     m_Output_time.clear();
00363     m_Output_time2.clear();
00364 
00365     m_t0 = m_T;     // Endzeit des letzten Durchlaufs wird zur neuen Startzeit
00366         m_a  = m_amax;
00367    
00368     return true;
00369 }
00370 
00371 /* Hilfsfunktion f�r die Zustellung. R�ckgabewert legt fest ob zuerst in z- oder in xy-Richtung zugestellt wird*/
00372 bool path_simulate::CheckConnect()
00373 {
00374     gp_Pnt tmp;
00375 
00376     // ab dem 2. lauf
00377     if (m_it1 != m_BSplineTop.begin() || m_it2 != m_BSplineBottom.begin())
00378     {
00379         m_StartPnts1.clear(); 
00380         m_StartPnts2.clear(); 
00381 
00382         // Berechne neue Verbindungspunkte f�r die Zustellung - MASTER -
00383                 m_it1--;
00384 
00385                 (*m_it1)->D0((*m_it1)->LastParameter(),tmp);  // Speichert Endpunkt der vorigen Master-Kurve in <tmp>                   
00386                 m_StartPnts1.push_back(tmp);                  // Pushe Endpunkt der vorigen Master-Kurve
00387                 
00388                 m_it1++; 
00389                 
00390                 (*m_it1)->D0((*m_it1)->FirstParameter(),tmp); // Speichert Startpunkt der vorigen Master-Kurve in <tmp>        
00391                 m_StartPnts1.push_back(tmp);                  // Pushe Startpunkt der aktuellen Master-Kurve
00392                                
00393         if (m_single == false) // Falls beidseitig gefahren wird, mache dasselbe, wie f�r den Slave (s.o.)
00394         {
00395             // Berechne neue Verbindungspunkte f�r die Zustellung - SLAVE -
00396             m_it2--; 
00397                         
00398                         (*m_it2)->D0((*m_it2)->LastParameter(),tmp); // Speichert Startpunkt der vorigen Slave-Kurve in <tmp> 
00399                         m_StartPnts2.push_back(tmp);                             // Pushe Endpunkt der vorigen Slave-Kurve
00400             
00401                         m_it2++;            
00402                           
00403             (*m_it2)->D0((*m_it2)->FirstParameter(),tmp); // Speichert Startpunkt der aktuellen Slave-Kurve in <tmp>             
00404                         m_StartPnts2.push_back(tmp);                  // Pushe Startpunkt der aktuellen Slave-Kurve
00405         }
00406     }
00407     else
00408     {
00409         return true;  // Erste zustellung immer gleich (in negativer z-Richtung)
00410     }
00411 
00412     if (m_StartPnts1[0].Z() - m_StartPnts1[1].Z() >= 0.0) return true;  // Zustellung in negativer z-Richtung
00413     else                                                  return false; // Zustellung in positiver z-Richtung
00414 }
00415 
00416 /* Hilfsfunktion f�r die Zustellung. R�ckgabewert legt fest ob zuerst in z- oder in xy-Richtung zugestellt wird*/
00417 bool path_simulate::CheckConnect(bool tool)
00418 {
00419     gp_Pnt tmp;
00420 
00421     // ab dem 2. lauf
00422     if (m_it1 != m_BSplineTop.begin() || m_it2 != m_BSplineBottom.begin())
00423     {
00424         if (m_Feat == true)  // F�r den Feature-Basierten Fall werden die Zustellungen von Master und Slave seperat behandelt   
00425                 {
00426                          if (!tool)
00427                          {
00428                                  m_StartPnts1.clear();
00429                                  
00430                                  m_it1--;
00431                                  
00432                                  (*m_it1)->D0((*m_it1)->LastParameter(),tmp);
00433                                  m_StartPnts1.push_back(tmp);  // Startpunkt
00434                                  
00435                                  m_it1++;
00436                                  
00437                                  (*m_it1)->D0((*m_it1)->FirstParameter(),tmp);
00438                                  m_StartPnts1.push_back(tmp);  // Zielpunkt
00439 
00440                                  if(m_StartPnts1[0].Z() - m_StartPnts1[1].Z() >= 0.0) return true;
00441                                  else                                                 return false;
00442                         }
00443                         else
00444                         {
00445                                  m_StartPnts2.clear();
00446                                  
00447                                  m_it2--;
00448                                  (*m_it2)->D0((*m_it2)->LastParameter(),tmp);
00449                                  m_it2++;
00450                                  m_StartPnts2.push_back(tmp);  // Startpunkt
00451 
00452                                  (*m_it2)->D0((*m_it2)->FirstParameter(),tmp);
00453                                  m_StartPnts2.push_back(tmp);  // Zielpunkt
00454 
00455                                  if(m_StartPnts2[0].Z() - m_StartPnts2[1].Z() >= 0.0) return true;
00456                                  else                                                 return false;
00457                         }
00458                 }
00459 
00460                 // Ab hier: Berechnung der Zustellungsvektoren f�r die synchrone Zustellung von Master und Slave
00461                 m_StartPnts1.clear();
00462                 m_StartPnts2.clear();
00463 
00464                 // Berechne neue Verbindungspunkte f�r die Zustellung - MASTER
00465                 m_it1--;
00466                 
00467                 (*m_it1)->D0((*m_it1)->LastParameter(),tmp);
00468                 m_StartPnts1.push_back(tmp);  // Startpunkt
00469                 
00470                 m_it1++;
00471                 
00472                 (*m_it1)->D0((*m_it1)->FirstParameter(),tmp);
00473                 m_StartPnts1.push_back(tmp);  // Zielpunkt
00474 
00475                 if (m_single == false)
00476                 {
00477                         // Berechne neue Verbindungspunkte f�r die Zustellung - SLAVE
00478                         m_it2--;
00479                         
00480                         (*m_it2)->D0((*m_it2)->LastParameter(),tmp);
00481                         m_StartPnts2.push_back(tmp);  // Startpunkt
00482                         
00483                         m_it2++;
00484                         
00485                         (*m_it2)->D0((*m_it2)->FirstParameter(),tmp);
00486                         m_StartPnts2.push_back(tmp);  // Zielpunkt
00487                 }
00488     }
00489     else
00490     {
00491         return true;  // erste Zustellung immer gleich
00492     }
00493 
00494     if (m_StartPnts1[0].Z() - m_StartPnts1[1].Z() >= 0.0) return true;
00495     else                                                  return false;
00496 }
00497 
00498 /* F�llt die Outputvektoren f�r die erste Zustellung. Der Eingabeparameter <brob> legt den Ausgabetyp fest*/
00499 bool path_simulate::ConnectPaths_xy(bool brob)
00500 {
00501     int N;
00502     double t = m_t0;
00503       
00504     std::vector<Base::Vector3d> tmp2;
00505         std::vector<double> d;
00506         Base::Vector3d tmp;
00507         
00508         gp_Pnt tmpPnt, pnt1, pnt2, p;
00509         gp_Vec vec_t(m_StartPnts1[0], m_StartPnts1[1]);
00510         
00511         if( 1e-3 > vec_t.Magnitude())  // keine Zustellung erforderlich
00512                 return true;
00513 
00514     if (m_single == false)
00515     {
00516         gp_Vec vec_1(m_StartPnts1[0], m_StartPnts1[1]); 
00517         gp_Vec vec_2(m_StartPnts2[0], m_StartPnts2[1]);
00518 
00519         gp_Vec2d vec_11, // Speichert Master-Zustellung in XY-Richtung
00520                              vec_21; // Speichert Master-Zustellung in  Z-Richtung
00521 
00522         vec_11.SetX(vec_1.X());  
00523         vec_11.SetY(vec_1.Y());
00524 
00525         if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())  // erster lauf -> xy zustellung (Slave)
00526         {
00527             vec_21.SetX(vec_2.X());
00528             vec_21.SetY(vec_2.Y());
00529         }
00530         else
00531         {
00532             vec_21.SetX(0.0);
00533             vec_21.SetY(vec_2.Z());  // slave zustellung in z-Richtung (ab 2.Lauf)
00534         }
00535 
00536         // Simulationsoutput
00537         if (brob == false)
00538         {
00539                         // ***** MASTER ******
00540             
00541                         ParameterCalculation_Line(vec_11.Magnitude());
00542 
00543             if (vec_11.Magnitude() != 0)
00544                 vec_11.Normalize();
00545 
00546             N = std::max(2, int(ceil((m_T - m_t0)/m_step))); // Anzahl der zu erzeugenden Outputwerte
00547             m_del_t = (m_T - m_t0)/N;                   // Zeitschrittweite
00548 
00549             for (int i=0; i<N; ++i)
00550             {
00551                                 // Erzeuge XY-Outputvektor
00552                 tmp.x = vec_11.X()*GetVelocity(t);
00553                 tmp.y = vec_11.Y()*GetVelocity(t);
00554                 tmp.z = 0.0;
00555 
00556                 tmp2.push_back(tmp);
00557                                 
00558                 m_Output.push_back(tmp2);
00559                                 m_Output_time.push_back(t);
00560                 
00561                                 t += m_del_t;
00562                                 tmp2.clear();
00563                         }
00564                          
00565                         m_Output_time.push_back(m_T);
00566 
00567                         // ***** SLAVE ******
00568                         t = m_t0;
00569                         ParameterCalculation_Line(vec_21.Magnitude());
00570 
00571             if (vec_21.Magnitude() != 0)
00572                   vec_21.Normalize();
00573 
00574             N = std::max(2, int(ceil((m_T - m_t0)/m_step)));  // Anzahl der zu erzeugenden Outputwerte
00575             m_del_t = (m_T - m_t0)/N;                    // Zeitschrittweite
00576 
00577             for (int i=0; i<N; ++i)
00578             {
00579                 if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00580                 {
00581                                         // Erzeuge XY-Outputvektor
00582                     tmp.x = vec_21.X()*GetVelocity(t);
00583                     tmp.y = vec_21.Y()*GetVelocity(t);
00584                     tmp.z = 0.0;
00585                 }
00586                 else
00587                 {
00588                                         // Erzeuge Z-Outputvektor
00589                     tmp.x = 0.0;
00590                     tmp.y = 0.0;
00591                     tmp.z = vec_21.Y()*GetVelocity(t);
00592                 }
00593 
00594                 tmp2.push_back(tmp);
00595                                 m_Output_time2.push_back(t);
00596                 m_Output2.push_back(tmp2);
00597                 
00598 
00599                                 t += m_del_t;
00600                                 tmp2.clear();
00601                         }
00602                
00603             m_Output_time2.push_back(m_T);
00604 
00605                         // Nullvektor
00606             tmp.x = 0.0;
00607             tmp.y = 0.0;
00608             tmp.z = 0.0;
00609 
00610             tmp2.push_back(tmp);
00611 
00612             m_Output.push_back(tmp2);
00613             m_Output2.push_back(tmp2);
00614         }
00615         else  // Roboter Output f�r den beidseitigen Fall
00616         {
00617             bool con = false;
00618 
00619             // hier wird die Anzahl <N> der Punkte f�r die Diskretisierung der Zustellungslinie berechnet
00620             if (vec_11.Magnitude() > vec_21.Magnitude()) N = std::max(2, int(ceil(vec_21.Magnitude()/TolDist)));
00621             else                                                     N = std::max(2, int(ceil(vec_11.Magnitude()/TolDist)));
00622 
00623             if (vec_11.Magnitude() == 0.0 && vec_21.Magnitude() == 0.0) N=0;
00624                         if (!m_conn) con = true;
00625 
00626             // Erster Punkt wird stets weggelassen
00627             if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00628             {
00629                                 // Startpunkt Master
00630                 tmp.x = m_StartPnts1[0].X();
00631                 tmp.y = m_StartPnts1[0].Y();
00632                 tmp.z = m_StartPnts1[0].Z();
00633                 
00634                                 m_Output_robo1.push_back(tmp);
00635                 RoboFlag_Master.push_back(0);
00636 
00637                                 // Startpunkt Slave
00638                 tmp.x = m_StartPnts2[0].X();
00639                 tmp.y = m_StartPnts2[0].Y();
00640                 tmp.z = m_StartPnts2[0].Z();
00641                 
00642                                 m_Output_robo2.push_back(tmp);
00643                 RoboFlag_Slave.push_back(0);
00644             }
00645 
00646             // Erzeuge Output - MASTER
00647             for (int i=1; i<N; ++i)
00648             {
00649                 tmp.x = m_StartPnts1[0].X() + (double(i)*vec_11.X())/(double(N)-1.0);
00650                 tmp.y = m_StartPnts1[0].Y() + (double(i)*vec_11.Y())/(double(N)-1.0);
00651                 tmp.z = m_StartPnts1[con].Z();
00652 
00653                 m_Output_robo1.push_back(tmp);
00654                 RoboFlag_Master.push_back(0);
00655             }
00656 
00657             // // Erzeuge Output - SLAVE
00658             for (int i=1; i<N; ++i)
00659             {
00660                 if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00661                 {
00662                     tmp.x = m_StartPnts2[0].X() + (double(i)*vec_21.X())/(double(N)-1.0);
00663                     tmp.y = m_StartPnts2[0].Y() + (double(i)*vec_21.Y())/(double(N)-1.0);
00664                     tmp.z = m_StartPnts2[0].Z();
00665                 }
00666                 else
00667                 {
00668                     tmp.x = m_StartPnts2[con].X();
00669                     tmp.y = m_StartPnts2[con].Y();
00670                     tmp.z = m_StartPnts2[0].Z() + (double(i)*vec_21.Y())/(double(N)-1.0);
00671                 }
00672                 
00673                                 m_Output_robo2.push_back(tmp);
00674                 RoboFlag_Slave.push_back(0);
00675             }
00676         }
00677     }
00678     else
00679     {
00680                 gp_Vec2d vec_11,vec_12;
00681         gp_Vec vec_1(m_StartPnts1[0], m_StartPnts1[1]);
00682 
00683         vec_11.SetX(vec_1.X());
00684         vec_11.SetY(vec_1.Y());
00685 
00686         if(brob == false)
00687         {
00688             ParameterCalculation_Line(vec_11.Magnitude());
00689 
00690             if(vec_11.Magnitude() != 0.0) 
00691                                 vec_11.Normalize();
00692 
00693                         N = std::max(2, (int)((m_T-m_t0)/m_step));
00694             m_del_t = (m_T-m_t0)/double(N);
00695 
00696             for(int i=0; i<N; ++i)
00697             {    
00698                                 // Erzeuge XY-Outputvektor
00699                 tmp.x = vec_11.X()*GetVelocity(t);
00700                 tmp.y = vec_11.Y()*GetVelocity(t);
00701                 tmp.z = 0.0;
00702 
00703                 tmp2.push_back(tmp);
00704 
00705                                 m_Output_time.push_back(t);
00706                 m_Output.push_back(tmp2);
00707                 
00708                 t += m_del_t;
00709                                 tmp2.clear();
00710             }
00711 
00712             m_Output_time.push_back(m_T);
00713 
00714                         // Nullvektor 
00715             tmp.x = 0.0;
00716             tmp.y = 0.0;
00717             tmp.z = 0.0;
00718 
00719             tmp2.push_back(tmp);
00720             m_Output.push_back(tmp2);
00721             tmp2.clear();
00722         }
00723         else
00724         {
00725             N = (int) vec_11.Magnitude();  // Anzahl der zu erzeugenden Outputwerte
00726 
00727             for (int i=0; i<N; ++i)
00728             {
00729                 tmp.x = m_StartPnts1[0].X() + (i*vec_11.X())/N;
00730                 tmp.y = m_StartPnts1[0].Y() + (i*vec_11.Y())/N;
00731                 tmp.z = m_StartPnts1[0].Z();
00732 
00733                 m_Output_robo1.push_back(tmp);
00734             }
00735         }
00736     }
00737     
00738         return true;
00739 }
00740 
00741 /* F�llt die Outputvektoren f�r die zweite Zustellung. Der Eingabeparameter <brob> legt den Ausgabetyp fest*/
00742 bool path_simulate::ConnectPaths_z(bool brob)
00743 {
00744     int N;
00745     double t = m_t0;
00746 
00747     Base::Vector3d tmp;
00748     std::vector<double> d;
00749     std::vector<Base::Vector3d> tmp2;
00750 
00751         gp_Vec vec_t(m_StartPnts1[0], m_StartPnts1[1]);
00752         if( 1e-3 > vec_t.Magnitude())
00753                 return true;
00754 
00755     if (m_single == false)
00756     {
00757         gp_Vec vec_1(m_StartPnts1[0], m_StartPnts1[1]);
00758         gp_Vec vec_2(m_StartPnts2[0], m_StartPnts2[1]);
00759 
00760         gp_Vec2d vec_11,vec_12;
00761 
00762         vec_11.SetX(0.0);
00763         vec_11.SetY(vec_1.Z());
00764 
00765         if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00766         {
00767             vec_12.SetX(0.0);
00768             vec_12.SetY(vec_2.Z());
00769         }
00770         else
00771         {
00772             vec_12.SetX(vec_2.X());
00773             vec_12.SetY(vec_2.Y());
00774         }
00775 
00776                 if (brob == false)
00777         {
00778                         // ***** MASTER ******            
00779                         ParameterCalculation_Line(vec_11.Magnitude());
00780 
00781             if (vec_11.Magnitude() != 0)
00782                 vec_11.Normalize();
00783 
00784             N = std::max(2, int(ceil((m_T - m_t0)/m_step)));  // Anzahl der zu erzeugenden Outputwerte
00785             m_del_t = (m_T - m_t0)/N;                    // Zeitschrittweite
00786 
00787             for (int i=0; i<N; ++i)
00788             {
00789                                 // Erzeuge Z-Outputvektor
00790                 tmp.x = 0.0;
00791                 tmp.y = 0.0;
00792                 tmp.z = vec_11.Y()*GetVelocity(t); 
00793 
00794                 tmp2.push_back(tmp);
00795                                 
00796                 m_Output.push_back(tmp2);
00797                                 m_Output_time.push_back(t);
00798                 
00799                                 t += m_del_t;
00800                                 tmp2.clear();
00801                         }
00802                          
00803                         m_Output_time.push_back(m_T);
00804 
00805                         // ***** SLAVE ******
00806                         t = m_t0;
00807                         ParameterCalculation_Line(vec_12.Magnitude());
00808 
00809             if (vec_12.Magnitude() != 0)
00810                   vec_12.Normalize();
00811 
00812             N = std::max(2, int(ceil((m_T - m_t0)/m_step)));  // Anzahl der zu erzeugenden Outputwerte
00813             m_del_t = (m_T - m_t0)/N;                    // Zeitschrittweite
00814 
00815             for (int i=0; i<N; ++i)
00816             {
00817                 if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00818                 {
00819                                         // Erzeuge Z-Outputvektor im allerersten Schritt
00820                     tmp.x = 0.0;
00821                     tmp.y = 0.0;
00822                     tmp.z = vec_12.Y()*GetVelocity(t);
00823                 }
00824                 else // Slave Zustellung in XY-Richtung
00825                 {
00826                                         // Erzeuge XY-Outputvektor
00827                     tmp.x = vec_12.X()*GetVelocity(t);   
00828                     tmp.y = vec_12.Y()*GetVelocity(t);
00829                     tmp.z = 0.0;
00830                 }
00831 
00832                 tmp2.push_back(tmp);
00833                                 m_Output_time2.push_back(t);
00834                 m_Output2.push_back(tmp2);
00835                 
00836 
00837                                 t += m_del_t;
00838                                 tmp2.clear();
00839                         }
00840                
00841             m_Output_time2.push_back(m_T);
00842 
00843             tmp.x = 0.0;
00844             tmp.y = 0.0;
00845             tmp.z = 0.0;
00846 
00847             tmp2.push_back(tmp);
00848 
00849             m_Output.push_back(tmp2);
00850             m_Output2.push_back(tmp2);
00851         }
00852         else  // Roboteroutput
00853         {
00854             if (vec_11.Magnitude() > vec_12.Magnitude()) std::max(2, N = int(ceil(vec_12.Magnitude()/TolDist)));  // Anzahl der zu erzeugenden Outputwerte
00855             else                                         std::max(2, N = int(ceil(vec_11.Magnitude()/TolDist)));  // Anzahl der zu erzeugenden Outputwerte
00856     
00857             if (vec_11.Magnitude() == 0.0 && vec_12.Magnitude() == 0.0) N=1;
00858 
00859             for (int i=1; i<N; ++i)
00860             {
00861                                 /*MASTER*/
00862 
00863                                 // Erzeuge Outputvektor f�r die Zustellung in Z-Richtung
00864                 tmp.x = m_StartPnts1[m_conn].X();
00865                 tmp.y = m_StartPnts1[m_conn].Y();
00866                 tmp.z = m_StartPnts1[0].Z() + (double(i)*vec_11.Y())/double(N-1);
00867 
00868                 m_Output_robo1.push_back(tmp);
00869                 RoboFlag_Master.push_back(0);
00870 
00871 
00872 
00873                                 /*SLAVE*/
00874 
00875                 if (m_it1 == m_BSplineTop.begin() && m_it2 == m_BSplineBottom.begin())
00876                 {   
00877                                         // Erzeuge Outputvektor f�r die Zustellung in Z-Richtung (nur im allerersten Schritt)
00878                     tmp.x = m_StartPnts2[1].X();
00879                     tmp.y = m_StartPnts2[1].Y();
00880                     tmp.z = m_StartPnts2[0].Z() + (double(i)*vec_12.Y())/double(N-1);
00881                 }
00882                 else
00883                 {
00884                                         // Erzeuge Outputvektor f�r die Zustellung in XY-Richtung
00885                     tmp.x = m_StartPnts2[0].X() + (double(i)*vec_12.X())/double(N-1);
00886                     tmp.y = m_StartPnts2[0].Y() + (double(i)*vec_12.Y())/double(N-1);
00887                     tmp.z = m_StartPnts2[m_conn].Z();
00888                 }
00889 
00890                 m_Output_robo2.push_back(tmp);
00891                 RoboFlag_Slave.push_back(0);
00892             }
00893         }
00894     }
00895     else
00896     {
00897         gp_Vec vec_1(m_StartPnts1[0], m_StartPnts1[1]);
00898         gp_Vec2d vec_12;
00899 
00900         vec_12.SetX(0.0);
00901         vec_12.SetY(vec_1.Z());
00902 
00903         if (brob == false)
00904         {
00905             ParameterCalculation_Line(vec_12.Magnitude());
00906                         
00907                         if (vec_12.Magnitude() != 0)
00908                   vec_12.Normalize();
00909 
00910             N = std::max(2, int(ceil((m_T - m_t0)/m_step)));  // Anzahl der zu erzeugenden Outputwerte
00911             m_del_t = (m_T - m_t0)/N;                    // Zeitschrittweite
00912 
00913             for (int i=0; i<N; ++i)
00914             {
00915                 m_Output_time.push_back(t);
00916 
00917                                 // Erzeuge Z-Outputvektor
00918                 tmp.x = 0.0;
00919                 tmp.y = 0.0;
00920                 tmp.z = vec_12.Y()*GetVelocity(t);
00921 
00922                 tmp2.push_back(tmp);
00923                 m_Output.push_back(tmp2);
00924                 
00925                 t += m_del_t;
00926                                 tmp2.clear();
00927             }
00928 
00929             t = m_T;
00930 
00931             m_Output_time.push_back(t);
00932 
00933                         // Nullvektor
00934             tmp.x = 0.0;
00935             tmp.y = 0.0;
00936             tmp.z = 0.0;
00937 
00938             tmp2.push_back(tmp);
00939             m_Output.push_back(tmp2);
00940             tmp2.clear();
00941         }
00942         else // Roboteroutput
00943         {
00944             N =(int) vec_12.Magnitude();  // Anzahl der zu erzeugenden Outputwerte
00945 
00946             for (int i=0; i<N; ++i)
00947             {
00948                                 // Erzeuge Outputvektor f�r die Zustellung in XY-Richtung
00949                 tmp.x = m_StartPnts1[0].X() + (i*vec_12.X())/N;
00950                 tmp.y = m_StartPnts1[0].Y() + (i*vec_12.Y())/N;
00951                 tmp.z = m_StartPnts1[0].Z();
00952 
00953                 m_Output_robo1.push_back(tmp);
00954             }
00955         }
00956     }
00957 
00958     return true;
00959 }
00960 
00961 /* F�llt die Outputvektoren f�r die Zustellung f�r den Feature-Basierten Fall. 
00962 Der Eingabeparameter <brob> legt den Ausgabetyp fest*/
00963 bool path_simulate::ConnectPaths_Feat(bool tool,  // Tool           (Master, Slave)
00964                                       bool brob,  // Ausgabetyp     (Roboter, Simulation)
00965                                       bool c_typ) // Zustellungsart (in zwei bzw. drei Schritten)
00966 {
00967     int N, ind;
00968     double rad, t;
00969     bool dir;
00970 
00971     std::vector<double> Times;
00972     std::vector<gp_Pnt> ConnPnts;
00973     std::vector< std::vector<Base::Vector3d> > Out;
00974     gp_Vec vec[3], vec_tmp[3];
00975 
00976     Base::Vector3d tmp;
00977     std::vector<double> d;
00978     std::vector<Base::Vector3d> tmp2;
00979     double vel;
00980 
00981     dir = CheckConnect(tool);  // setze Starpunkte neu
00982 
00983     if (!tool)
00984     {
00985         ConnPnts = m_StartPnts1;
00986         rad = m_set.master_radius;
00987     }
00988     else
00989     {
00990         ConnPnts = m_StartPnts2;
00991         rad = m_set.slave_radius;
00992     }
00993 
00994     if (c_typ)  // Zustellung in 2 Schritten
00995     {
00996         ind = 2;
00997         vec_tmp[0].SetCoord(0.0, 0.0, abs(ConnPnts[1].Z()-ConnPnts[0].Z()));
00998         vec_tmp[1].SetCoord(ConnPnts[1].X()-ConnPnts[0].X(), ConnPnts[1].Y()-ConnPnts[0].Y(), 0.0);
00999 
01000         if (dir) // tool  (Master/Slave) muss runter fahren
01001         {
01002             if (!tool)
01003             {
01004                 vec[0] =  vec_tmp[1];    // tool = Master
01005                 vec[1] = -vec_tmp[0];
01006             }
01007             else
01008             {
01009                 vec[0] = -vec_tmp[0];    // tool = Slave
01010                 vec[1] =  vec_tmp[1];
01011             }
01012         }
01013         else   // tool  (Master/Slave) muss hoch fahren
01014         {
01015             if (!tool)
01016             {
01017                 vec[0] = vec_tmp[0];    // tool = Master
01018                 vec[1] = vec_tmp[1];
01019             }
01020             else
01021             {
01022                 vec[0] = vec_tmp[1];    // tool = Slave
01023                 vec[1] = vec_tmp[0];
01024             }
01025         }
01026     }
01027     else // Zustellung in 3 Schritten
01028     {
01029         ind = 3;
01030 
01031         vec_tmp[0].SetCoord(0.0, 0.0, rad);
01032         vec_tmp[1].SetCoord(ConnPnts[1].X()-ConnPnts[0].X(), ConnPnts[1].Y()-ConnPnts[0].Y(), 0.0);
01033         vec_tmp[2].SetCoord(0.0, 0.0, abs(ConnPnts[1].Z()-ConnPnts[0].Z()) + rad);
01034 
01035         if (dir) // tool  (Master/Slave) muss runter fahren
01036         {
01037             if (!tool)
01038             {
01039                 vec[0] =  vec_tmp[0];    // tool = Master
01040                 vec[1] =  vec_tmp[1];
01041                 vec[2] = -vec_tmp[2];
01042             }
01043             else
01044             {
01045                 vec[0] = -vec_tmp[2];    // tool = Slave
01046                 vec[1] =  vec_tmp[1];
01047                 vec[2] =  vec_tmp[0];
01048             }
01049         }
01050         else   // tool  (Master/Slave) muss hoch fahren
01051         {
01052             if (!tool)
01053             {
01054                 vec[0] =  vec_tmp[2];    // tool = Master
01055                 vec[1] =  vec_tmp[1];
01056                 vec[2] = -vec_tmp[0];
01057             }
01058             else
01059             {
01060                 vec[0] = -vec_tmp[0];    // tool = Slave
01061                 vec[1] =  vec_tmp[1];
01062                 vec[2] =  vec_tmp[2];
01063             }
01064         }
01065     }
01066 
01067     if (brob) // Roboteroutput
01068         {   
01069                 for (int i=0; i<ind; ++i)
01070                 {
01071                         N = std::max(2, int(ceil(vec[i].Magnitude()/TolDist)));  // Anzahl der zu erzeugenden Outputwerte
01072 
01073                         for(int j=1; j<N; ++j)
01074                         {
01075                                 tmp.x = ConnPnts[0].X() + (double(j)*vec[i].X())/(double(N)-1.0);
01076                                 tmp.y = ConnPnts[0].Y() + (double(j)*vec[i].Y())/(double(N)-1.0);
01077                                 tmp.z = ConnPnts[0].Z() + (double(j)*vec[i].Z())/(double(N)-1.0);;
01078 
01079                                 if(!tool) m_Output_robo1.push_back(tmp);  // Master
01080                                 else      m_Output_robo2.push_back(tmp);  // Slave
01081                         }
01082 
01083                         ConnPnts[0].SetCoord(tmp.x , tmp.y, tmp.z); // Setze Startpunkt = Endpunkt f�r die n�chste Iteration
01084                 }
01085 
01086                 return true;
01087         }
01088         
01089         if(ConnPnts[0].Distance(ConnPnts[1]) < 1e-3) return true;  // keine Zustellung bei Spiralbahnen !!!
01090 
01091     for (int i=0; i<ind; ++i)
01092     {
01093         t = m_t0;
01094         ParameterCalculation_Line(vec[i].Magnitude());
01095         if (vec[i].Magnitude() != 0.0) vec[i].Normalize();
01096         else continue;
01097 
01098         N = std::max(2,(int) ceil((m_T - m_t0)/m_step)); // Anzahl der zu erzeugenden Outputwerte
01099         m_del_t = (m_T - m_t0)/N;                   // Zeitschrittweite
01100 
01101         for (int j=0; j<N; ++j)
01102         {
01103             Times.push_back(t);
01104             vel = GetVelocity(t);
01105 
01106             tmp.x = vec[i].X()*vel;
01107             tmp.y = vec[i].Y()*vel;
01108             tmp.z = vec[i].Z()*vel;
01109 
01110             tmp2.push_back(tmp);
01111             Out.push_back(tmp2);  // F�lle tempor�ren Output-Vektor (wird weiter unten zugewiesen)
01112 
01113             t += m_del_t;
01114                         tmp2.clear();
01115         }
01116 
01117         m_t0 = m_T; // Endzeit des letzten Durchlaufs wird zur neuen Startzeit
01118     }
01119 
01120     Times.push_back(m_T);
01121 
01122     tmp.x = 0.0;
01123     tmp.y = 0.0;
01124     tmp.z = 0.0;
01125 
01126     tmp2.clear();
01127     tmp2.push_back(tmp);
01128     Out.push_back(tmp2);
01129 
01130     if(!tool)
01131     {
01132         m_Output      = Out;
01133         m_Output_time = Times;
01134     }
01135     else
01136     {
01137         m_Output2      = Out;
01138         m_Output_time2 = Times;
01139     }
01140 
01141     return true;  
01142 }
01143 
01144 /* Hier wird unter Ber�cksichtigung der Kr�mmungstoleranz <curvTOL> eine Unterteilung der Kurve vorgenommen.
01145 Die Bereichsgrenzen werden im R�ckgabevektor zur�ckgeliefert. Der Ausgabevektor ist leer wenn die maximale Kr�mmung
01146 den Toleranzwert nicht �berschreitet und somit auch keine Unterteilung notwendig ist */ 
01147 std::vector<std::vector<double> > path_simulate::CompBounds(bool tool,std::vector<double> knots)
01148 {
01149         m_curMax = 0.0; // setze maximale Kr�mmung initial auf Null     
01150         double cr_bound = 1/curvTOL;
01151         double cr_last;
01152         gp_Vec dtmp1, dtmp2;
01153         gp_Pnt dtmp0;
01154     GeomAdaptor_Curve curve;
01155         std::vector<double> single_bound;
01156     std::vector<double> bounds;
01157     std::vector<std::vector<double> > CriticalBounds;
01158 
01159     // lade aktuelle Kurve
01160     if (!tool)  curve.Load(*m_it1);
01161     else        curve.Load(*m_it2);
01162 
01163     double fParam = curve.FirstParameter(), // Erster Kurvenparameter
01164            lParam = curve.LastParameter(),  // Letzter Kurvenparameter
01165            period = lParam - fParam;        // L�nge des Parameterbereichs
01166  
01167 
01168         int n  = knots.size();  // L�nge des Knotenvektors
01169         bool b = false;
01170 
01171         // Hier erfolgt die Berechnung der maximalen Kr�mmung <m_curMax>
01172         // Die Parameter der Bereichsgrenzen an denen die Kurvenkr�mmung dem Toleranzwert <cr_bound> 
01173         // entspricht werden in den Vektor <bounds> f�r die weitere Nachbearbeitung gef�llt
01174     for (int i=0; i<n; ++i)
01175     {
01176                 curve.D2(knots[i], dtmp0, dtmp1, dtmp2); // Da es sich um eine kubische B-Spline Kurve handelt,
01177                                                          // kann die maximale Kr�mmung nur an den Knotenpunkten angenomen werden
01178                 if(dtmp2.Magnitude() >= cr_bound && !b)
01179                 {
01180                         if(knots[i] >= m_boundTol && knots[i] < lParam - m_boundTol)
01181                         {
01182                                 if(cr_last < cr_bound)
01183                                 {
01184                                         bounds.push_back(knots[i-1] + (knots[i] - knots[i-1])*
01185                                                                       (cr_last - cr_bound)/
01186                                                                                           (cr_last - dtmp2.Magnitude()));
01187                                 }
01188                                 else
01189                                 {
01190                                         bounds.push_back(fParam + m_boundTol);
01191                                 }
01192                                 b = true;
01193                         }
01194                 }
01195                 
01196                 if(dtmp2.Magnitude() < cr_bound && b)
01197                 {
01198                         if(knots[i] <= lParam - m_boundTol)
01199                         {
01200                                 bounds.push_back(knots[i-1] + (knots[i] - knots[i-1])*
01201                                                                   (cr_bound - cr_last)/
01202                                                                                           (dtmp2.Magnitude() - cr_last));
01203                         }
01204                         else
01205                         {
01206                                 bounds.push_back(lParam - m_boundTol);
01207                                 
01208                         }
01209                         b = false;
01210                 }
01211                 
01212                 cr_last = dtmp2.Magnitude(); // Kr�mmung entspricht hier dem Betrag der zweiten Ableitung
01213                         
01214                 if(m_curMax < cr_last)  // Speichert maximale Kr�mmung
01215                         m_curMax = cr_last;
01216         }
01217 
01218         if(period < 2*m_boundTol || bounds.size() == 0)
01219                 return CriticalBounds;
01220 
01221         if(b) bounds.push_back(lParam - m_boundTol);  // Hier muss evtl. noch die letzte Grenze eingef�gt werden
01222 
01223         n = (int) bounds.size()/2;  // <bounds> hat stets gerade L�nge
01224         for(int i=0; i<n; i++)      // Fasse Bereiche welche einen geringeren Abstand als <m_boundTol> haben zusammen
01225         {
01226                 single_bound.push_back(bounds[2*i]);
01227                 
01228                 while(i<n-1 && bounds[2*i+2] - bounds[2*i+1] < m_boundTol)
01229                         i++;
01230                 
01231                 single_bound.push_back(bounds[2*i+1]);
01232         CriticalBounds.push_back(single_bound);
01233         single_bound.clear();
01234     }
01235 
01236     return CriticalBounds;
01237 }
01238 
01239 /* Hier wird die Vorarbeit f�r die Funktion Gen_Path() geleistet.
01240 Die Vektoren <m_length>, <m_velocity>, <m_accel> werden f�r die aktuelle Kurve gef�llt.*/ 
01241 bool path_simulate::CompPath(bool tool) // tool = 0  -> Master
01242                                         // tool = 1  -> Slave
01243 {
01244         m_boundTol = pow(m_vmax, 2.0)/m_amax; // Toleranzbereich vor kritischen Bereichen (notwendig zum Hochbeschleunigen)
01245         
01246         double cur     = 1.0/curvTOL,         // Kr�mmungstoleranz f�r die Kurvenunterteilung
01247                pos     = 0.0, 
01248                cur_tmp = 0.0;
01249 
01250         int    nb_knots;
01251 
01252         std::vector<std::vector<double> > v_vec;
01253         std::vector<double> v(3), l_vec, a_vec;
01254         
01255         std::vector<Base::Vector3d> Pnt1Vec;
01256     
01257         GeomAdaptor_Curve curve;
01258 
01259     gp_Pnt pnt0;
01260     gp_Vec pnt, pnt1, pnt2, vec;
01261     Base::Vector3d Pnt1;
01262     
01263     double start,
01264                    fParam,
01265            lParam,
01266                    period;
01267 
01268         double d2, velo, tetha, 
01269                    len, len_1;
01270    
01271         double t0 = m_t0; // �bergibt aktuelle Startzeit
01272 
01273         int num = Detect_FeatCurve(tool);  // Liefert Anzahl der zu fahrenden Kurven (i.d.R. num = 1) 
01274         
01275         for(int a=0; a<num; a++)  // Schleife �ber die zusammenh�ngenden Kurven
01276         {
01277                 // lade aktuelle kurven
01278             if (!tool)  curve.Load(*m_it1);
01279                 else        curve.Load(*m_it2);
01280 
01281                 // setze Parameter neu
01282                 fParam = curve.FirstParameter();
01283                 lParam = curve.LastParameter();
01284                 period = lParam - fParam;
01285 
01286                 // �bergibt Starparameter der aktuellen Kurve
01287                 m_StartParam[tool] = fParam;
01288                 start = m_StartParam[tool];
01289                 
01290                 // *** Berechnung des Knotenvektors ***
01291                 if (!tool)
01292                 {
01293                         nb_knots = (*m_it1)->NbKnots();
01294                         m_Knots  = new TColStd_Array1OfReal(0,nb_knots-1);
01295                    (*m_it1)->Knots(*m_Knots);
01296                 }
01297                 else
01298                 {
01299                         nb_knots = (*m_it2)->NbKnots();
01300                         m_Knots  = new TColStd_Array1OfReal(0,nb_knots-1);
01301                    (*m_it2)->Knots(*m_Knots);
01302                 }
01303                 
01304                 std::vector<double> knot_vec(m_Knots->Length());
01305                 for(int i=0; i<m_Knots->Length(); i++)
01306                         knot_vec[i] = m_Knots->Value(i);
01307 
01308                 // *** Ende der Berechnung des Knotenvektors ***
01309 
01310 
01311                 std::vector<std::vector<double> > CriticalBounds = 
01312                                                         CompBounds(tool, knot_vec); // Berechnet auf Basis der aktuellen Kurve, 
01313                                                                                                                                             // die kritischen Bereiche im Parameterraum und 
01314                                                                                                                                             // berechnet gleichzeitig die maximale Kurvenkr�mmung <m_curMax>
01315                 
01316                 m_vmid = std::min(m_vmax,sqrt(m_amax/m_curMax)); // Legt Geschwindigkeit fest mit der allen kritischen Bereiche     
01317                                                             // abgefahren werden
01318 
01319 Newtry: // Falls die generierten Wegl�ngen nicht ausreichen, dann wird ein neuer Versuch mit halbem <m_vmid> gestartet
01320                 
01321                 v[0] = 0.0;  // starte jede Kurve mit v = 0
01322                 int m = 0;
01323 
01324                 for (unsigned int i=0; i<CriticalBounds.size(); ++i)  // Schleife �ber einzelne Unterteilungsbereiche
01325                 {
01326                         d2 = 0.0;
01327                         pos = m_Knots->Value(m);
01328 
01329                         while(pos < m_StartParam[tool])
01330                         {
01331                                 m++;
01332                                 pos = m_Knots->Value(m);
01333                         }
01334                         
01335                         /*------------------- Gerader Bereich ---------------------*/
01336                         
01337                         while(pos < CriticalBounds[i][0]) // Berechnung der maximalen Kr�mmung dieses geraden Bereichs
01338                         {
01339                                 curve.D2(pos, pnt0, pnt1, pnt2);
01340                                 cur_tmp = pnt2.Magnitude();   // Kr�mmung am aktuellen Punkt
01341                                 
01342                                 if(d2 < cur_tmp) 
01343                                         d2 = cur_tmp;             // Speichert maximale Kr�mmung dieses geraden Bereichs
01344 
01345                                 m++;
01346                                 pos = m_Knots->Value(m);
01347                         }
01348 
01349                         tetha = 0.6 + 0.25*sqrt(d2/m_curMax);         // Setzt tetha-parameter -> (0.6 < tetha < 0.85)
01350                         velo = std::min(m_vmax, tetha*(sqrt(m_amax/d2)));  // Setzt maximale Geschwindigkeit <velo>
01351                         m_a = m_amax - d2*velo*velo;                  // wenn <velo> zu gro� gew�hlt wurde, kann <m_a> evtl. negativ werden
01352 
01353                         // Korrektur
01354                         while(m_a <= 0.0)
01355                         {
01356                                 velo = velo/2.0;
01357                                 m_a = m_amax - d2*velo*velo;
01358                         }
01359 
01360                         if(velo < m_vmid)
01361                                 m_vmid = velo;
01362 
01363                         v[1] = velo;
01364 
01365                         /*-------------- Korrektur der Geschwindigkeiten (falls der Weg zu lang) -------------*/
01366 
01367                         len = CriticalBounds[i][0] - m_StartParam[tool];              // L�nge des i. geraden Abschnitts
01368                         len_1 = (pow(v[1] - v[0],2.0) + pow(v[1] - m_vmid,2.0))/m_a;  // notwendige L�nge
01369 
01370                         if(len < pow(v[0] - m_vmid,2.0)/m_a)  // f�r diesen Fall ist keine Korrektur m�glich
01371                         {
01372                                 l_vec.clear();
01373                                 v_vec.clear();
01374                                 a_vec.clear();
01375 
01376                                 m_StartParam[tool] = start; // setze Startparameter zur�ck
01377                             m_vmid = m_vmid/2;          // halbiere kritische Durchlaufgeschwindigkeit
01378                                 goto Newtry;
01379                         }
01380 
01381                         while(len < len_1)
01382                         {
01383                                 v[1] = v[0] + (v[1] - v[0])/2.0;
01384                                 len_1 = (pow(v[1] - v[0],2.0) + pow(v[1] - m_vmid,2.0))/m_a; 
01385                         }
01386 
01387                         v[2] = m_vmid;
01388 
01389                         /*---Korrekturende---*/ 
01390 
01391                         // F�lle Vektoren
01392                         l_vec.push_back(len);  // L�nge
01393                         v_vec.push_back(v);    // Geschwindigkeiten
01394                         a_vec.push_back(m_a);  // Beschleunigung
01395                 
01396                         m_StartParam[tool] += len;   // setzt Startparameter neu
01397 
01398                         /*------------------------ gekr�mmter Bereich ------------------------*/
01399 
01400                         len = CriticalBounds[i][1] - CriticalBounds[i][0];  // Bogenl�nge des gekr�mmten Bereichs
01401                         m_StartParam[tool] += len;                          // setzt Startparameter neu
01402                         v[0] = v[2];                                        // Endgeschwindigkeit wird zur Startgeschwindigkeit
01403                         
01404                         l_vec.push_back(len);
01405                 }
01406 
01407                 d2 = 0; 
01408                 
01409                 // Korrigiere aktuellen Knotenparameter
01410                 while(pos < m_StartParam[tool])
01411                 {
01412                         m++;
01413                         pos = m_Knots->Value(m);
01414                 }
01415 
01416                 pos = m_Knots->Value(m);
01417             
01418                 // Berechnung der maximalen Kr�mmung f�r den letzten Abschnitt
01419                 while(pos < lParam)
01420                 {               
01421                         curve.D2(pos, pnt0, pnt1, pnt2);
01422                     
01423                         Pnt1.x = pnt2.X();
01424                         Pnt1.y = pnt2.Y();
01425                         Pnt1.z = pnt2.Z();
01426          
01427                         if(d2 < Pnt1.Length()) d2 = Pnt1.Length();
01428 
01429                         m++;
01430                         pos = m_Knots->Value(m);
01431                 }
01432 
01433                 tetha = 0.6 + 0.25*sqrt(d2/m_curMax);        // 0.6 < tetha < 0.85
01434                 velo = std::min(m_vmax, tetha*(sqrt(m_amax/d2))); // vgl. oben
01435                         
01436                 v[1] = velo;
01437                 v[2] = 0.0;
01438                 m_a = m_amax - d2*velo*velo; // wenn velo zu gro� gew�hlt wurde, kann m_a negativ werden
01439 
01440                 // Korrektur
01441                 while(m_a <= 0.0)
01442                 {
01443                         velo = velo/2.0;
01444                         v[1] = velo;
01445                         m_a = m_amax - cur*velo*velo;
01446                 }
01447 
01448                 d2 = 0;
01449 
01450                 len = lParam - m_StartParam[tool] + start;          // L�nge des letzten geraden Abschnitts
01451                 len_1 = (pow(v[1] - v[0],2.0) + pow(v[1],2.0))/m_a; // notwendige L�nge
01452 
01453                 if(len < pow(v[0],2.0)/m_a) // hier keine Korrektur m�glich
01454                 {
01455                         l_vec.clear();
01456                         v_vec.clear();
01457                         a_vec.clear();
01458 
01459                         m_StartParam[tool] = start; // setze Startparameter zur�ck
01460                         m_vmid = m_vmid/2;          // halbiere kritische Durchlaufgeschwindigkeit und versuchs erneut
01461                         goto Newtry;
01462                 }
01463 
01464                 while(len < len_1)
01465                 {
01466                         v[1] = v[0] + (v[1] - v[0])/2;
01467                         len_1 = (pow(v[1] - v[0],2.0) + pow(v[1],2.0))/m_a; 
01468                 }
01469 
01470                 // F�lle Vektoren
01471                 l_vec.push_back(len);  // L�nge
01472                 v_vec.push_back(v);    // Geschwindigkeiten
01473                 a_vec.push_back(m_a);  // Beschleunignung
01474                 
01475                 // F�lle hier erst die Ausgabevektoren (einmal pro Kurve)
01476                 if(tool)
01477                 {       
01478                         m_length_sl.push_back(l_vec);
01479                         m_velocity_sl.push_back(v_vec);
01480                         m_accel_sl.push_back(a_vec);
01481                 }
01482                 else
01483                 {
01484                         m_length_ma.push_back(l_vec);
01485                         m_velocity_ma.push_back(v_vec);
01486                         m_accel_ma.push_back(a_vec);
01487                 }
01488 
01489                 // lade aktuelle kurven
01490             if (!tool)  m_it1++;
01491                 else        m_it2++;
01492 
01493                 m_StartParam[tool] = start;
01494                 
01495                 l_vec.clear();
01496                 v_vec.clear();
01497                 a_vec.clear();
01498                 
01499                 curve.Delete();
01500                 CriticalBounds.clear();
01501         }
01502 
01503         // Setze Iterator und Startparameter wieder zur�ck
01504         if (!tool)
01505         { 
01506                 for(int i=0; i<num; i++){m_it1--;}
01507                 m_StartParam[tool] = (*m_it1)->FirstParameter();
01508                 
01509         }
01510         else
01511         { 
01512                 for(int i=0; i<num; i++){m_it2--;}
01513                 m_StartParam[tool] = (*m_it2)->FirstParameter();
01514         }
01515 
01516     return true;
01517 }
01518 
01519 /* Integriert erst nach der Trapezregel die Outputwerte nach der Zeit und liefert den Fehlervektor als Verbindung von Start- und Endpunkt.
01520 Abschlie�end erfolgt die Korrektur der Outputvektoren um eben diesen Fehlervektor */
01521 bool path_simulate::Correction(bool tool)
01522 {
01523     int N;
01524     gp_Vec vec;
01525         gp_Pnt pnt;
01526     Base::Vector3d tmp;
01527     std::vector<Base::Vector3d> tmp2;
01528 
01529         double Sum[3];
01530 
01531         Sum[0] = 0.0;
01532     Sum[1] = 0.0;
01533     Sum[2] = 0.0;
01534 
01535         // Hier erfolgt die numerische Integration des Outputvektors nach der Trapezregel und der
01536         // entstehende Fehlervektor wird in <vec> abgelegt
01537     if (tool==false) // Master
01538     {
01539                 N = m_Output.size();
01540         for (int i=1; i<N; ++i)
01541         {
01542             Sum[0] += (m_Output[i][0].x + m_Output[i-1][0].x)*(m_Output_time[i] - m_Output_time[i-1]) / 2.0;
01543             Sum[1] += (m_Output[i][0].y + m_Output[i-1][0].y)*(m_Output_time[i] - m_Output_time[i-1]) / 2.0;
01544             Sum[2] += (m_Output[i][0].z + m_Output[i-1][0].z)*(m_Output_time[i] - m_Output_time[i-1]) / 2.0;
01545         }
01546 
01547                 if(m_StartPnts1[0].Distance(m_StartPnts1[1]) > 1e-3)  // falls Kurve NICHT geschlossen
01548                 {
01549                         vec.SetCoord(Sum[0],Sum[1],Sum[2]);
01550                         vec.SetCoord(m_StartPnts1[1].X() - m_StartPnts1[0].X() - vec.X(),
01551                                                  m_StartPnts1[1].Y() - m_StartPnts1[0].Y() - vec.Y(),
01552                                                  m_StartPnts1[1].Z() - m_StartPnts1[0].Z() - vec.Z());
01553                 }
01554                 else
01555                         vec.SetCoord(-Sum[0],-Sum[1],-Sum[2]);
01556     }
01557     else  // Slave
01558     {
01559                 N = m_Output2.size();
01560         for (int i=1; i<N; ++i)
01561         {
01562             Sum[0] += (m_Output2[i][0].x + m_Output2[i-1][0].x)*(m_Output_time2[i] - m_Output_time2[i-1]) / 2.0;
01563             Sum[1] += (m_Output2[i][0].y + m_Output2[i-1][0].y)*(m_Output_time2[i] - m_Output_time2[i-1]) / 2.0;
01564             Sum[2] += (m_Output2[i][0].z + m_Output2[i-1][0].z)*(m_Output_time2[i] - m_Output_time2[i-1]) / 2.0;
01565         }
01566 
01567                 if(m_StartPnts2[0].Distance(m_StartPnts2[1]) > 1e-3)  // falls Kurve NICHT geschlossen
01568                 {
01569                         vec.SetCoord(Sum[0],Sum[1],Sum[2]);
01570                         vec.SetCoord(m_StartPnts2[1].X() - m_StartPnts2[0].X() - vec.X(),
01571                                                  m_StartPnts2[1].Y() - m_StartPnts2[0].Y() - vec.Y(),
01572                                                  m_StartPnts2[1].Z() - m_StartPnts2[0].Z() - vec.Z());
01573                 }
01574                 else
01575                         vec.SetCoord(-Sum[0],-Sum[1],-Sum[2]);
01576     }
01577 
01578     ParameterCalculation_Line(vec.Magnitude());  // Berechnung der Zeitgrenzen
01579 
01580     N = (int) ceil((m_T - m_t0)/m_step);  // Anzahl der zu erzeugenden Outputwerte
01581     m_del_t = (m_T - m_t0)/N;             // Zeitschrittweite
01582 
01583     if (N==1)  // Nur ein Outputvektor
01584     {
01585         m_T = m_t0 + 2e-3;
01586 
01587         if (tool==false) // Master
01588         {
01589             m_Output_time.push_back(m_t0);
01590             m_Output_time.push_back(m_t0 + 1e-3);
01591         }
01592         else // Slave
01593         {
01594             m_Output_time2.push_back(m_t0);
01595             m_Output_time2.push_back(m_t0 + 1e-3);
01596         }
01597 
01598         tmp.x = 0.0;
01599         tmp.y = 0.0;
01600         tmp.z = 0.0;
01601 
01602         tmp2.push_back(tmp);
01603 
01604         if(tool==false)  m_Output.push_back(tmp2);  // f�llt Master-Output
01605         else             m_Output2.push_back(tmp2); // f�llt Slave-Output
01606 
01607         tmp2.clear();
01608 
01609         tmp.x = (vec.X()/vec.Magnitude())*(vec.X()/1e-3);
01610         tmp.y = (vec.Y()/vec.Magnitude())*(vec.Y()/1e-3);
01611         tmp.z = (vec.Z()/vec.Magnitude())*(vec.Z()/1e-3);
01612 
01613         tmp2.push_back(tmp);
01614 
01615         if (tool==false) m_Output.push_back(tmp2);
01616         else             m_Output2.push_back(tmp2);
01617 
01618         tmp2.clear();
01619     }
01620     else
01621     {
01622         double vel,t = m_t0;
01623         if (vec.Magnitude() != 0) vec.Normalize();
01624 
01625         for (int i=0; i<N; ++i)
01626         {
01627             if (tool==false) m_Output_time.push_back(t);
01628             else             m_Output_time2.push_back(t);
01629 
01630             // MASTER
01631                         vel = GetVelocity(t);
01632 
01633                         // Ausgabevektor zum Zeitpunkt <t>
01634                         tmp.x = vec.X()*vel;
01635             tmp.y = vec.Y()*vel;
01636             tmp.z = vec.Z()*vel;
01637 
01638             tmp2.push_back(tmp);
01639           
01640                         if (tool==false) m_Output.push_back(tmp2);
01641             else             m_Output2.push_back(tmp2);
01642 
01643             t += m_del_t;
01644             tmp2.clear();
01645         }
01646     }
01647 
01648         // Nullvektor
01649         tmp.x = 0.0;
01650     tmp.y = 0.0;
01651     tmp.z = 0.0;
01652     
01653         tmp2.push_back(tmp);
01654         
01655         // �bergebe Nullvektor zur Endzeit <m_T>
01656         if (tool==false) 
01657         {
01658                 m_Output.push_back(tmp2);
01659                 m_Output_time.push_back(m_T);
01660         }
01661     else
01662         {
01663                 m_Output2.push_back(tmp2);
01664                 m_Output_time2.push_back(m_T);
01665         }
01666 
01667     return true;
01668 }
01669 // Hier wird der eigentliche Output f�r den Simulationsprozess generiert unter der Ber�cksichtigung 
01670 // der in CompPath() berechneten Vektoren m_velocity, m_accel, m_length
01671 bool path_simulate::Gen_Path()
01672 {
01673         int n,m;        
01674         double length, lam, t_start, t_ma, t_sl, t_tmp; 
01675 
01676         t_start = m_t0;                           // setze Startzeit
01677         m_StartPnts1[0] = (*m_it1)->StartPoint(); // setze Startparameter
01678 
01679         if(m_single == false)
01680         {
01681                 m_StartPnts2[0] = (*m_it2)->StartPoint();
01682 
01683 /*------------------------------ Berechne Durchlaufzeit f�r das Master-Tool --------------------------------*/
01684 
01685                 n = m_velocity_ma.size();
01686                 for(int i=0; i<n; i++)                    // Schleife �ber die (zusammenh�ngenden) Kurven 
01687                 {
01688                         m = m_velocity_ma[i].size();       
01689                         for(int j=0; j<m; j++)                // Schleife �ber die einzelnen Unterteilungsgebiete 
01690                         {
01691                                 m_v[0] = m_velocity_ma[i][j][0];  // Startgeschwindigkeit des i-ten Abschnitts
01692                                 m_v[1] = m_velocity_ma[i][j][1];  // maximale Geschwindigkeit des i-ten Abschnitts
01693                                 m_v[2] = m_velocity_ma[i][j][2];  // Endgeschwindigkeit des i-ten Abschnitts
01694 
01695                                 m_a = m_accel_ma[i][j];
01696 
01697                                 length = m_length_ma[i][2*j];      // L�nge des unkritischen Abschnitts 
01698                                                                                                    // Bem: Jede Kurve beginnt und endet in einem unkritischen Abschnitt
01699                                 ParameterCalculation_Curve(length);   // Hier wird die Endzeit m_T berechnet
01700 
01701                                 if(j != m-1)
01702                                 {
01703                                         length = m_length_ma[i][2*j+1];// L�nge des kritischen Abschnitts 
01704                                         m_T = m_T + length/m_v[2];     // Berechnet neue Endzeit (kritische Abschnitte werden mit konstanter
01705                                                                                                    // Geschwindigkeit m_v[2] durchlaufen)
01706                                 }
01707 
01708                                 m_t0 = m_T;                        // Endzeit wird zur Startzeit
01709                         }
01710                 }
01711 
01712                 t_ma = m_T - t_start;                  // Entspricht Durchlaufzeit f�r den Master
01713                 m_t0 = t_start;                        // Setzt Startzeit zur�ck
01714 
01715 /*-------------------------- Berechnung der Durchlaufzeit f�r das Slave-Tool -------------------------------*/
01716 
01717                 n = m_velocity_sl.size();
01718                 for(int i=0; i<n; i++)                    // Schleife �ber die (zusammenh�ngenden) Kurven 
01719                 {
01720                         m = m_velocity_sl[i].size();       
01721                         for(int j=0; j<m; j++)                // Schleife �ber die einzelnen Unterteilungsgebiete 
01722                         {
01723                                 m_v[0] = m_velocity_sl[i][j][0];  // Startgeschwindigkeit des i-ten Abschnitts
01724                                 m_v[1] = m_velocity_sl[i][j][1];  // maximale Geschwindigkeit des i-ten Abschnitts
01725                                 m_v[2] = m_velocity_sl[i][j][2];  // Endgeschwindigkeit des i-ten Abschnitts
01726 
01727                                 m_a = m_accel_sl[i][j];
01728 
01729                                 length = m_length_sl[i][2*j];      // L�nge des unkritischen Abschnitts 
01730                                                                                                    // Bem: Jede Kurve beginnt und endet in einem unkritischen Abschnitt
01731                                 ParameterCalculation_Curve(length);// Hier wird u.a. die Endzeit <m_T> berechnet
01732 
01733                                 if(j != m-1)
01734                                 {
01735                                         length = m_length_sl[i][2*j+1];// L�nge des kritischen Abschnitts 
01736                                         m_T = m_T + length/m_v[2];     // Berechnet neue Endzeit (kritische Abschnitte werden mit der konstanten
01737                                                                                                    // Geschwindigkeit <m_v[2]> durchlaufen)
01738                                 }
01739 
01740                                 m_t0 = m_T;                        // Endzeit wird zur Startzeit
01741                         }
01742                 }
01743                                                                                                                                                            
01744                 t_sl = m_T - t_start;                              // Entspricht Durchlaufzeit f�r den Slave
01745                 m_t0 = t_start;                                            // Setzt Startzeit zur�ck
01746                                                 
01747 /*----------------------- Synchronisierung von Master und Slave -----------------------------*/
01748 
01749 // Idee: Skaliere die Geschwindigkeiten und Beschleunigungen derjenigen Bahn mit der k�rzeren Durchlaufzeit,
01750 // so dass die Durchlaufzeiten f�r Master und Slave �bereinstimmen
01751 
01752                 
01753                 if(t_ma <= t_sl)                                           
01754                 {
01755                         // Ab hier: Korrektur f�r den Master
01756 
01757                         lam = t_ma/t_sl;  // Skalierungsfaktor 0 < lam <= 1
01758                         
01759                         // Zun�chst werden alle Geschwindigkeiten runterskaliert
01760                         n = m_velocity_ma.size();
01761                         for(int i=0; i<n; i++)
01762                         {
01763                                 m = m_velocity_ma[i].size();
01764                                 for(int j=0; j<m; j++)
01765                                 {
01766                                         // linearen Beziehung zwischen den Geschwindigkeiten und der Durchlaufzeit
01767                                         m_velocity_ma[i][j][0] = lam*m_velocity_ma[i][j][0];
01768                                         m_velocity_ma[i][j][1] = lam*m_velocity_ma[i][j][1];
01769                                         m_velocity_ma[i][j][2] = lam*m_velocity_ma[i][j][2];
01770                                 }
01771                         }
01772 
01773                         // Skalierung der Beschleunigungen
01774                         n = m_accel_ma.size();
01775                         for(int i=0; i<n; i++)
01776                         {
01777                                 m = m_accel_ma[i].size();
01778                                 for(int j=0; j<m; j++)
01779                                         m_accel_ma[i][j] = lam*lam*m_accel_ma[i][j];  // Die Beschleunigungen m�ssen mit dem Quadrat des Skalierungsfaktors
01780                         }                                                     // multipliziert werden (quadratische Abh�ngigkeit zur Durchlaufzeit)
01781                 }
01782                 else
01783                 {
01784                         // Ab hier: Korrektur f�r den Slave
01785 
01786                         lam = t_sl/t_ma;  // Skalierungsfaktor 0 < lam <= 1
01787                         
01788                         // Zun�chst werden alle Geschwindigkeiten runterskaliert
01789                         n = m_velocity_sl.size();
01790                         for(int i=0; i<n; i++)
01791                         {
01792                                 m = m_velocity_sl[i].size();
01793                                 for(int j=0; j<m; j++)
01794                                 {
01795                                         // vgl. Master
01796                                         m_velocity_sl[i][j][0] = lam*m_velocity_sl[i][j][0];
01797                                         m_velocity_sl[i][j][1] = lam*m_velocity_sl[i][j][1];
01798                                         m_velocity_sl[i][j][2] = lam*m_velocity_sl[i][j][2];
01799                                 }
01800                         }
01801 
01802                         // Skalierung der Beschleunigungen
01803                         n = m_accel_sl.size();
01804                         for(int i=0; i<n; i++)
01805                         {
01806                                 m = m_accel_sl[i].size();
01807                                 for(int j=0; j<m; j++)
01808                                         m_accel_sl[i][j] = lam*lam*m_accel_sl[i][j];  // Die Beschleunigungen m�ssen mit dem Quadrat des Skalierungsfaktors
01809                         }                                                     // multipliziert werden
01810                 }
01811         }
01812 
01813 /*------------------------------- Generierung der Outputvektoren ------------------------------------*/
01814         
01815 /*MASTER*/      
01816         
01817         bool l;
01818         int  q,p;
01819 
01820         n = m_length_ma.size();
01821         for(int i=0; i<n; i++)  // Schleife geht �ber die Anzahl der zu fahrenden Kurven, vgl. path_simulate::CompPath()
01822         {
01823                 if(i!=0)
01824                         m_it1++;
01825 
01826                 l = false;  // Legt fest ob wir uns gerade in einem kritischen Abschnitt befinden
01827                 q = 0;      // Zu Beginn jeder Kurve auf Null
01828             p = 0;      // Zu Beginn jeder Kurve auf Null
01829 
01830                 m_StartParam[0] = (*m_it1)->FirstParameter(); // Setzt Startparameter der aktuellen Kurve
01831                 
01832                 m = m_length_ma[i].size();
01833                 for(int j=0; j<m; j++)
01834                 {
01835                         if(l==false)  // wird in jedem zweiten Schritt aufgerufen
01836                         {
01837                                 m_a = m_accel_ma[i][p];
01838                                 
01839                                 m_v[0] = m_velocity_ma[i][q][0];
01840                                 m_v[1] = m_velocity_ma[i][q][1];
01841                                 m_v[2] = m_velocity_ma[i][q][2];
01842                                 
01843                                 p++;
01844                                 q++;
01845                         }
01846 
01847                         MakePathSingle(0,m_length_ma[i][j],l,0);  // Hier werden die Outputvektoren erzeugt
01848                         
01849                         // Update der Variablen 
01850                         m_StartParam[0] += m_length_ma[i][j];
01851                         m_t0 = m_T;
01852                         l = !l;
01853                 }
01854         }
01855 
01856         m_t0 = t_start;
01857 
01858 /*ENDE MASTER*/
01859 
01860         
01861 /*SLAVE*/
01862         
01863         // Analog zum Master (s.o.)
01864         if(m_single == false)
01865         {
01866                 n = m_length_sl.size();
01867                 for(int i=0; i<n; i++)
01868                 {
01869                         if(i!=0)
01870                                 m_it2++;
01871                         
01872                         l = false;
01873                         q = 0;
01874                         p = 0;
01875                         m_StartParam[1] = (*m_it2)->FirstParameter();
01876                         m = m_length_sl[i].size();
01877 
01878                         // vgl. Master
01879                         for(int j=0; j<m; j++)
01880                         {
01881                                 if(l==false)
01882                                 {
01883                                         m_a = m_accel_sl[i][p];
01884                                         
01885                                         m_v[0] = m_velocity_sl[i][q][0];
01886                                         m_v[1] = m_velocity_sl[i][q][1];
01887                                         m_v[2] = m_velocity_sl[i][q][2];
01888                                         
01889                                         p++;
01890                                         q++;
01891                                 }
01892 
01893                                 MakePathSingle(0,m_length_sl[i][j],l,1);  // hier wird der output f�r den slave generiert
01894                                 m_StartParam[1] += m_length_sl[i][j];
01895                                 m_t0 = m_T;
01896                                 l = !l;
01897                         }
01898                 }
01899         }
01900 
01901 /*ENDE SLAVE*/
01902 
01903 
01904 /*WEG-KORREKTUR*/
01905         
01906         t_tmp = m_t0;
01907 
01908         m_StartPnts1[1] = (*m_it1)->EndPoint(); // Setzt Endpunkt, notwendig f�r die folgende Wegkorrektur
01909         Correction(0);                          // Wegkorrektur f�r den Master
01910 
01911         if(m_single == false)
01912         {
01913                 m_t0 = t_tmp;
01914                 m_StartPnts2[1] = (*m_it2)->EndPoint(); // Setzt Endpunkt, notwendig f�r die folgende Wegkorrektur
01915                 Correction(1);                          // Wegkorrektur f�r den Slave
01916         }
01917 
01918         m_t0 = t_start;
01919 
01920 /*ENDE WEG-KORREKTUR*/
01921 
01922 
01923         m_velocity_ma.clear();
01924         m_velocity_sl.clear();
01925         m_length_ma.clear();
01926         m_length_sl.clear();
01927         m_accel_ma.clear();
01928         m_accel_sl.clear();
01929         
01930         return true;
01931 }
01932 
01933 /* Hier werden die Simulations-Outputvektoren f�r die jeweiligen Kurvenabschnitte erzeugt */
01934 bool path_simulate::MakePathSingle(bool   brob,   // Beschreibt Ausgabeart (Roboter, Simulation) 
01935                                                                    double length, // Bogenl�nge des betrachteten Abschnitts
01936                                                                    bool   part,   // Gibt an ob wir einen kritischen Abschnitt betrachten
01937                                                                    bool   tool)   // Tool (Master, Slave)
01938 {
01939     GeomAdaptor_Curve anAdaptorCurve;
01940     double firstParam, lastParam, param, period, d, velo;
01941     int N;
01942 
01943     if(tool == false) anAdaptorCurve.Load(*m_it1);  // Master
01944     else              anAdaptorCurve.Load(*m_it2);  // Slave
01945 
01946     firstParam = anAdaptorCurve.FirstParameter();
01947     lastParam  = anAdaptorCurve.LastParameter();
01948     period     = lastParam - firstParam;
01949    
01950         gp_Vec                      dtmp1, dtmp2;   
01951         gp_Pnt                      tmp;
01952     Base::Vector3d              tmp2;
01953     std::vector<Base::Vector3d> tmp3;
01954 
01955         // Base::Vector3f pnt1,pnt2;
01956 
01957         if(brob)
01958         {
01959                 N = std::max(2, (int) ceil(period / double(TolDist)));
01960 
01961                 for (int i=1; i<N; ++i)  // niemals den ersten punkt mitnehmen
01962                 {
01963                         if (m_StartParam[tool] + double(i)*period/(double(N)-1.0) > lastParam)
01964                         {
01965                                 anAdaptorCurve.D0(m_StartParam[tool] + double(i)*period/(double(N)-1.0) - period, tmp);
01966                         }
01967                         else if (m_StartParam[tool] + double(i)*period/(double(N)-1.0) < firstParam )
01968                         {
01969                                 anAdaptorCurve.D0(m_StartParam[tool] + double(i)*period/(double(N)-1.0) + period, tmp);
01970                         }
01971                         else
01972                         {
01973                                 anAdaptorCurve.D0(m_StartParam[tool] + double(i)*period/(double(N)-1.0), tmp);
01974                         }
01975 
01976                         tmp2.x = tmp.X();
01977                         tmp2.y = tmp.Y();
01978                         tmp2.z = tmp.Z();
01979 
01980                         if (!tool)
01981                         {
01982                                 m_Output_robo1.push_back(tmp2);
01983 
01984                                 if (i==1)
01985                                 {
01986                                         RoboFlag_Master.pop_back();
01987                                         RoboFlag_Master.push_back(1);
01988                                 }
01989 
01990                                 RoboFlag_Master.push_back(0);
01991                         }
01992                         else
01993                         {
01994                                 m_Output_robo2.push_back(tmp2);
01995 
01996                                 if (i==1)
01997                                 {
01998                                         RoboFlag_Slave.pop_back();
01999                                         RoboFlag_Slave.push_back(1);
02000                                 }
02001 
02002                                 RoboFlag_Slave.push_back(0);
02003                         }
02004                 }
02005 
02006                 return true;
02007         }
02008 
02009     if (part==true) m_T = m_t0 + length/m_v[2]; // kritische Bereiche werden mit konstanter Geschwindigkeit durchlaufen
02010     else            ParameterCalculation_Curve(length);
02011     
02012         N = std::max(2, (int)((m_T-m_t0)/m_step));
02013 
02014     if (N>=100000) 
02015         N = 99999;  // maximale Anzahl m�glicher Outputwerte
02016 
02017         m_del_t = (m_T-m_t0)/double(N);
02018 
02019     std::vector< std::vector<Base::Vector3d> > D0;
02020     std::vector< std::vector<Base::Vector3d> > D1;
02021 
02022     double t = m_t0;
02023 
02024         //anAdaptorCurve.D0(m_StartParam[tool],tmp);
02025         //pnt2.Set(tmp.X(),tmp.Y(),tmp.Z());
02026 
02027         if (part == true)  // kritischer Abschnitt
02028     {
02029         for (int i=0; i<N; ++i)  // Hauptschleife
02030         {
02031             if (!tool) m_Output_time.push_back(t);
02032             else       m_Output_time2.push_back(t);
02033 
02034             d = m_v[2]*(t-m_t0);
02035                         param = m_StartParam[tool] + d; // Kurvenparameter entspricht zur�ckgelegtem Weg 
02036                                                         // f�r den Fall einer Bogenl�ngenparametrisierung.                      
02037                                                         // Bei beliebiger Parametrisierung: 
02038                                                         // param = FindParamAt(anAdaptorCurve, d, m_StartParam[tool]);
02039 
02040                         // Berechnet alles bis zur zweiten Ableitung
02041                         if      ( param > lastParam  ){ anAdaptorCurve.D2(param - period, tmp, dtmp1, dtmp2);}
02042             else if ( param < firstParam ){ anAdaptorCurve.D2(param + period, tmp, dtmp1, dtmp2);}
02043                         else                          { anAdaptorCurve.D2(param,          tmp, dtmp1, dtmp2);}
02044 
02045                         //m_times_tmp.push_back(t);
02046                     //m_velo_tmp.push_back(m_v[2]);
02047 
02048                         // Ausgabevektor zum Zeitpunkt <t>
02049                         tmp2.x = dtmp1.X()*m_v[2];
02050             tmp2.y = dtmp1.Y()*m_v[2];
02051             tmp2.z = dtmp1.Z()*m_v[2];
02052 
02053             tmp3.push_back(tmp2);
02054             
02055                         if (!tool) m_Output.push_back(tmp3);
02056             else       m_Output2.push_back(tmp3);
02057             
02058                         tmp3.clear();
02059                         
02060                         /*
02061                         if (tool == false)  // zeichnet den tats�chlichen Weg nach
02062                         {
02063                                 pnt1 = pnt2;
02064                                 
02065                                 pnt2.x = pnt2.x + dtmp1.X()*m_v[2]*m_del_t;
02066                                 pnt2.y = pnt2.y + dtmp1.Y()*m_v[2]*m_del_t;
02067                                 pnt2.z = pnt2.z + dtmp1.Z()*m_v[2]*m_del_t;
02068                                 
02069                                 if(i==0)
02070                                         m_log.addSingleArrow(pnt1,pnt2,2,1,1,1);
02071                                 else
02072                                         m_log.addSingleArrow(pnt1,pnt2,2,1,0,0);
02073                         }
02074                         */
02075             
02076                         t += m_del_t;
02077         }
02078         return true;
02079     }
02080 
02081     // unkritischer Abschnitt
02082     for (int i=0; i<N; ++i)
02083     {
02084         if (!tool) m_Output_time.push_back(t);
02085         else       m_Output_time2.push_back(t);
02086         
02087                 d = GetDistance(t);
02088                 param = m_StartParam[tool] + d;     // Kurvenparameter entspricht zur�ckgelegtem Weg 
02089                                                         // f�r den Fall einer Bogenl�ngenparametrisierung.                      
02090                                                         // Bei beliebiger Parametrisierung: 
02091                                                         // param = FindParamAt(anAdaptorCurve, d, m_StartParam[tool]);
02092 
02093                 // Berechnet alles bis zur zweiten Ableitung
02094         if      ( param > lastParam  ){ anAdaptorCurve.D2(param - period, tmp, dtmp1, dtmp2);}
02095         else if ( param < firstParam ){ anAdaptorCurve.D2(param + period, tmp, dtmp1, dtmp2);}
02096                 else                          { anAdaptorCurve.D2(param,          tmp, dtmp1, dtmp2);}
02097 
02098                 velo = GetVelocity(t);  // Berechnet die Geschwindigkeit <velo> des Tools zum Zeitpunkt <t>
02099                                         // bzgl. den Parametern m_t0, m_t1, m_t2, m_T, m_a, m_v[i], i =1,2,3 
02100 
02101                 // Ausgabevektor zum Zeitpunkt <t>
02102         tmp2.x = dtmp1.X()*velo;
02103         tmp2.y = dtmp1.Y()*velo;
02104         tmp2.z = dtmp1.Z()*velo;
02105 
02106         tmp3.push_back(tmp2);
02107        
02108                 if (!tool) m_Output.push_back(tmp3);
02109         else       m_Output2.push_back(tmp3);
02110 
02111                 tmp3.clear();
02112                 
02113                 /*
02114                 if (tool == false)  // zeichnet den tats�chlichen Weg nach
02115                 {
02116                         pnt1 = pnt2;
02117                         
02118                         pnt2.x = pnt2.x + dtmp1.X()*velo*m_del_t;
02119                         pnt2.y = pnt2.y + dtmp1.Y()*velo*m_del_t;
02120                         pnt2.z = pnt2.z + dtmp1.Z()*velo*m_del_t;
02121                         
02122                         if(i==0)
02123                                 m_log.addSingleArrow(pnt1,pnt2,2,1,1,1);
02124                         else
02125                                 m_log.addSingleArrow(pnt1,pnt2,2,1,0,0);
02126                 }
02127                 */
02128 
02129                 //m_times_tmp.push_back(t);
02130                 //m_velo_tmp.push_back(velo);
02131 
02132         t += m_del_t;
02133     }
02134 
02135         return true;
02136 }
02137 
02138 /* Hauptroutine zur Generierung des Roboteroutputs f�r den normalen beidseitigen Fall */
02139 bool path_simulate::MakePathRobot()
02140 {
02141     ofstream anOutputFile;
02142     ofstream anOutputFile2;
02143 
02144     anOutputFile.open("output_master.k");
02145     anOutputFile.precision(7);
02146         
02147         anOutputFile  << "none" << std::endl;
02148 
02149     if (m_single == false)
02150     {
02151         anOutputFile2.open("output_slave.k");
02152         anOutputFile2.precision(7);
02153                 
02154                 anOutputFile2 << "none" << std::endl;
02155     }
02156 
02157         // Outputgenerierung �ber alle Kurven
02158     for (m_it1 = m_BSplineTop.begin(); m_it1 != m_BSplineTop.end(); ++m_it1)
02159     {
02160         m_StartParam[0] = ((*m_it1)->FirstParameter());
02161         if (m_single == false) m_StartParam[1] = ((*m_it2)->FirstParameter());
02162 
02163         /*------ 1.ZUSTELLUNG ------*/
02164         
02165                 m_conn = CheckConnect();
02166         
02167                 if (m_conn)   ConnectPaths_xy(1);
02168         else          ConnectPaths_z(1);
02169 
02170         UpdateParam();
02171         
02172 
02173                 /*------ 2.ZUSTELLUNG ------*/
02174         
02175                 if (m_conn)   ConnectPaths_z(1);
02176         else          ConnectPaths_xy(1);
02177 
02178         UpdateParam();
02179 
02180        
02181                 /*------ KURVE ------*/
02182 
02183                 MakePathSingle(1,0,0,0);  // Master
02184         MakePathSingle(1,0,0,1);  // Slave
02185         UpdateParam();
02186 
02187         if (m_single==false && (m_it1 != (m_BSplineTop.end()-1)))
02188             ++m_it2;
02189 
02190     }
02191 
02192         int c = 1;
02193 
02194         /*--- Schreibe Roboter-Output ---*/
02195 
02196         if (m_single==false)
02197         {
02198                 WriteOutputDouble(anOutputFile,anOutputFile2,c,c,1,beam);
02199                 anOutputFile2 << "*END" << endl;
02200                 anOutputFile2.close();
02201         }
02202         else
02203         {
02204                 WriteOutputSingle(anOutputFile,c,1,0,beam);
02205         }
02206     
02207         anOutputFile  << "*END" << endl;
02208     anOutputFile.close();
02209 
02210     return true;
02211 }
02212 
02213 /* Wird nur zu Beginn der Ausschreibung in path_simulate::WriteOurputDouble() aufgerufen und passt die Ausgabevektoren
02214 <m_Output_time>, <m_Output_time2> so aneinander an, dass die Endzeiten �bereinstimmen*/ 
02215 bool path_simulate::TimeCorrection()
02216 {
02217         int N;
02218         Base::Vector3d vec(0.0,0.0,0.0);
02219     std::vector<Base::Vector3d> vecc;
02220         
02221         vecc.push_back(vec);
02222     
02223     if (m_single == false)  // Eine Zeitkorrektur macht nur f�r diesen Fall auch Sinn
02224     {
02225         if(m_Output_time.size() == 0 || m_Output_time2.size() == 0)  // Sonderbehandlung f�r diesen Fall
02226                 {
02227                         if(m_Output_time.size() > m_Output_time2.size())
02228                         {
02229                                 m_Output_time2 = m_Output_time;
02230                                 N = m_Output_time2.size();
02231                                 m_Output2.resize(N);
02232                                 
02233                                 for (int i=0; i<N; ++i) // F�llt leeren Output mit Nullvektoren (Werkzeug hat zu warten)
02234                                 {
02235                                         m_Output2[i] = vecc; 
02236                                 }
02237 
02238                                 return true;
02239                         }
02240                         else if(m_Output_time2.size() > m_Output_time.size())
02241                         {
02242                                 m_Output_time = m_Output_time2;
02243                                 N = m_Output_time.size();
02244                                 m_Output.resize(N);
02245                                 
02246                                 for (int i=0; i<N; ++i) // F�llt leeren Output mit Nullvektoren (-> Werkzeug hat zu warten)
02247                                 {
02248                                         m_Output[i] = vecc;
02249                                 }
02250 
02251                                 return true;
02252                         }
02253 
02254                         return true;  //gibt true zur�ck wenn beide Outputvektoren <m_Output_time> und <m_Output_time2> leer sein sollten
02255                 }
02256 
02257         if (m_Output_time[m_Output_time.size()-1] < m_Output_time2[m_Output_time2.size()-1])
02258         {
02259             m_T = m_Output_time2[m_Output_time2.size()-1];
02260 
02261             N = std::max(1,int(ceil((m_Output_time2[m_Output_time2.size()-1] - m_Output_time[m_Output_time.size()-1])/ m_step)));
02262             m_del_t = (m_Output_time2[m_Output_time2.size()-1] - m_Output_time[m_Output_time.size()-1])/double(N);
02263 
02264             int ind = m_Output_time.size()-1;
02265             double time = 0.0;
02266 
02267             for (int i=1; i<N; ++i)
02268             {
02269                 time += m_del_t;
02270                 m_Output_time.push_back(m_Output_time[ind] + time);
02271                 m_Output.push_back(vecc);
02272             }
02273 
02274             m_Output_time.push_back(m_Output_time2[m_Output_time2.size()-1]);
02275             m_Output.push_back(vecc);
02276         }
02277         else if (m_Output_time[m_Output_time.size()-1] > m_Output_time2[m_Output_time2.size()-1])
02278         {
02279             m_T = m_Output_time[m_Output_time.size()-1];
02280 
02281             N = std::max(1,int(ceil((m_Output_time[m_Output_time.size()-1] - m_Output_time2[m_Output_time2.size()-1])/ m_step)));
02282             m_del_t = (m_Output_time[m_Output_time.size()-1] - m_Output_time2[m_Output_time2.size()-1])/double(N);
02283 
02284             int ind = m_Output_time2.size()-1;
02285             double time = 0.0;
02286 
02287             for (int i=1; i<N; ++i)
02288             {
02289                 time += m_del_t;
02290                 m_Output_time2.push_back(m_Output_time2[ind] + time);
02291                 m_Output2.push_back(vecc);
02292             }
02293 
02294             m_Output_time2.push_back(m_Output_time[m_Output_time.size()-1]);
02295             m_Output2.push_back(vecc);
02296         }
02297     }
02298     else // falls <m_single> = true (d.h nur Master -> keine Zeitkorrektur erforderlich!!!)
02299     {
02300         return false;
02301     }
02302 
02303     return true;
02304 }
02305 
02306 /* Hauptroutine zur Generierung des Simulationsoutputs f�r den feature-basierten und spiral-basierten beidseitigen Fall */
02307 bool path_simulate::MakePathSimulate_Feat(const std::vector<float> &flatAreas, bool spiral)
02308 {
02309     m_Feat = true;
02310         
02311         double rad[2];
02312         bool   tool;
02313         int    c[2];
02314     
02315     gp_Pnt pnt0, pnt1;
02316 
02317     std::vector<Handle_Geom_BSplineCurve>::iterator *it_1,*it_2;
02318     std::vector<Handle_Geom_BSplineCurve> *curves_1, *curves_2;
02319 
02320     ofstream anOutputFile[2];
02321 
02322     anOutputFile[0].open("output_master.k");
02323     anOutputFile[1].open("output_slave.k");
02324         anOutputFile[0].precision(7);
02325     anOutputFile[1].precision(7);
02326 
02327     m_it1 = m_BSplineTop.begin();
02328     m_it2 = m_BSplineBottom.begin();
02329 
02330     rad[0] =  m_set.master_radius;
02331     rad[1] = - m_set.slave_radius - m_set.sheet_thickness;
02332 
02333     c[0] = 1;    // Start Index der Master Kurven
02334     c[1] = 2001; // Start Index der Slave  Kurven
02335 
02336     int i = 0;
02337 
02338     while (m_it1 != m_BSplineTop.end() && m_it2 != m_BSplineBottom.end())
02339     {
02340         tool = StartingTool();  // bestimmt welches tool warten muss:
02341                                                                 // tool == true  : Roboter = Slave  & NC = Master
02342                                                                 // tool == fasle : Roboter = Master & NC = Slave
02343                 if (!tool)
02344                 {
02345                         it_1 = &m_it1;
02346                         it_2 = &m_it2;
02347                         curves_1 = &m_BSplineTop;
02348                         curves_2 = &m_BSplineBottom;
02349                 }
02350                 else
02351                 {
02352                         it_1 = &m_it2;
02353                         it_2 = &m_it1;
02354                         curves_1 = &m_BSplineBottom;
02355                         curves_2 = &m_BSplineTop;
02356                 }
02357        
02358         m_StartParam[0] = ((*m_it1)->FirstParameter()); // setze neue Startparameter (in unserem Fall immer 0)
02359         
02360                 if (m_single == false) 
02361                         m_StartParam[1] = ((*m_it2)->FirstParameter());
02362  
02363                 // die erste Zustellung vor dem Kontakt mit dem Blech wird hier seperat gehandelt
02364         if (i==0)
02365         {
02366             /*------ ZUSTELLUNG 1 ------*/
02367             ConnectPaths_xy(0);
02368             WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam);
02369             UpdateParam();
02370 
02371             /*------ ZUSTELLUNG 2 ------*/
02372             ConnectPaths_z(0);
02373             WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam);
02374             UpdateParam();
02375         }
02376 
02377         while (true)
02378         {
02379             if (*it_1 != (*curves_1).end()-1)
02380             {
02381                                 /* ------ Kurve ------*/
02382                 CompPath(0);                                                                                                             // Berechne Parameter f�r den Master
02383                                 CompPath(1);                                                                                                             // Berechne Parameter f�r den Slave
02384                                 Gen_Path();                                                                                                              // Erzeuge Output f�r aktuelle Kurve
02385                                 WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02386                 UpdateParam();
02387 
02388                                 /*------ Zustellung ------*/
02389                 (*it_1)++;                                                                                               // Gehe zur n�chsten Kurve
02390                 ConnectPaths_Feat(tool, 0, 1);                                                                           // Erzeuge Output f�r Zustellung
02391                                 WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02392                 UpdateParam();
02393 
02394                 if (*it_1 == (*curves_1).end()-1 && *it_2 == (*curves_2).end()-1)    // Letzter Schritt
02395                 {
02396                                         /* ------ Kurve ------*/
02397                                         CompPath(0);  // Berechne Parameter f�r den Master
02398                                         CompPath(1);  // Berechne Parameter f�r den Slave
02399                                         Gen_Path();       // Erzeuge Output f�r aktuelle Kurve
02400                                         WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02401                                         UpdateParam();
02402                     break;
02403                 }
02404 
02405                 (**it_1)->D0((**it_1)->FirstParameter(),pnt0); // �bergebe aktuellen Startpunkt
02406 
02407                 
02408                 if ((pnt0.Z() > (flatAreas[i+1] + rad[tool] - 1e-1)) &&  // Erreicht der MASTER den n�chsten ebenen 
02409                     (pnt0.Z() < (flatAreas[i+1] + rad[tool] + 1e-1)))    // Bereich, muss auf den SLAVE gewartet werden
02410                 {
02411                                         if(!spiral)  // Bei Spiralbahnen erfolgt die Zustellung sofort
02412                                         {
02413                                                 /* ------ Kurve ------*/
02414                                                 CompPath(0);  // Berechne Parameter f�r den Master
02415                                                 CompPath(1);  // Berechne Parameter f�r den Slave
02416                                                 Gen_Path();       // Erzeuge Output f�r aktuelle Kurve
02417                                                 WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02418                                                 UpdateParam();
02419                                         }
02420                                         break;
02421                 }
02422             }
02423             else
02424             {
02425                 if (*it_2 == (*curves_2).end()-1)  // letzter Schritt
02426                 {
02427                                         /* ------ Kurve ------*/
02428                     CompPath(0);  // Berechne Parameter f�r den Master
02429                                         CompPath(1);  // Berechne Parameter f�r den Slave
02430                                         Gen_Path();       // Erzeuge Output f�r aktuelle Kurve
02431                                         WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02432                                         UpdateParam();
02433                     break;
02434                 }
02435                 else break;
02436             }
02437         }
02438 
02439         if (m_it1 == m_BSplineTop.end()-1 && m_it2 == m_BSplineBottom.end()-1) // Fertig !!!
02440             break;
02441 
02442                 /* ------ Zustellung ------*/
02443                 if(!spiral) 
02444                 {
02445                         (*it_1)++;                                              // gehe zur n�chsten Kurve
02446                         ConnectPaths_Feat(tool, 0, 1);  // Erzeuge Output f�r die Master-Zustellung
02447                 }
02448                 
02449                 (*it_2)++;                                                                                                                       // gehe zur n�chsten Kurve                                                                              
02450                 ConnectPaths_Feat(!tool, 0, 0);                                                                  // Erzeuge Output f�r die Slave-Zustellung
02451                 WriteOutputDouble(anOutputFile[0],anOutputFile[1],c[0],c[1],0,beam); // Schreibe Output
02452                 UpdateParam();
02453         
02454                 ++i;
02455     }
02456 
02457     anOutputFile[0] << "*END" << endl;
02458     anOutputFile[1] << "*END" << endl;
02459         anOutputFile[0].close();
02460     anOutputFile[1].close();
02461 
02462         //WriteTimes();
02463 
02464     return true;
02465 }
02466 
02467 /* Hauptroutine zur Generierung des Roboteroutputs f�r den feature-basierten und spiral-basierten beidseitigen Fall */
02468 bool path_simulate::MakePathRobot_Feat(const std::vector<float> &flatAreas)
02469 {
02470     m_Feat = true;
02471     int f = 0, run;
02472     bool tool;
02473     double rad[2];
02474     gp_Pnt pnt0, pnt1;
02475 
02476     std::vector<Handle_Geom_BSplineCurve>::iterator *it_1,*it_2;
02477     std::vector<Handle_Geom_BSplineCurve> *curves_1, *curves_2;
02478 
02479     ofstream anOutputFile[2];
02480 
02481         std::stringstream master_file, slave_file;
02482 
02483     m_it1 = m_BSplineTop.begin();
02484     m_it2 = m_BSplineBottom.begin();
02485 
02486     rad[0] =  m_set.master_radius;
02487     rad[1] = - m_set.slave_radius - m_set.sheet_thickness;
02488 
02489     int i = 0;
02490 
02491     while (m_it1 != m_BSplineTop.end() && m_it2 != m_BSplineBottom.end())
02492     {
02493         tool = StartingTool();  // Bestimmt welches tool warten muss
02494 
02495         // Setze Startparameter (in unserem Fall unn�tig da immer 0)
02496         m_StartParam[0] = ((*m_it1)->FirstParameter());
02497         if (m_single == false) m_StartParam[1] = ((*m_it2)->FirstParameter());
02498 
02499         // Erste Zustellung wird seperat gehandelt
02500         if (i==0)
02501         {
02502             ConnectPaths_xy(1); /* 1. ZUSTELLUNG */
02503             ConnectPaths_z(1);  /* 2. ZUSTELLUNG */
02504         }
02505 
02506         if (!tool)
02507         {
02508             it_1 = &m_it1;
02509             it_2 = &m_it2;
02510             curves_1 = &m_BSplineTop;
02511             curves_2 = &m_BSplineBottom;
02512         }
02513         else
02514         {
02515             it_1 = &m_it2;
02516             it_2 = &m_it1;
02517             curves_1 = &m_BSplineBottom;
02518             curves_2 = &m_BSplineTop;
02519         }
02520 
02521         // Hauptschleife
02522         while (true)
02523         {
02524             MakePathSingle(1,0,0,tool);  // Bahngenerierung des kontinuierlich fahrenden tools f�r aktuelle kurve
02525 
02526             // MASTER
02527             if (*it_1 != (*curves_1).end()-1)
02528             {
02529                 (*it_1)++;
02530                 (**it_1)->D0((**it_1)->FirstParameter(),pnt0);
02531 
02532                 if (*it_1 == (*curves_1).end()-1 && *it_2 == (*curves_2).end()-1)
02533                 {
02534                     ConnectPaths_Feat(tool, 1, 1);
02535                     MakePathSingle(1,0,0,tool);
02536                     break;
02537                 }
02538 
02539                 if ((pnt0.Z() > (flatAreas[i+1] + rad[tool] - 1e-1)) &&
02540                     (pnt0.Z() < (flatAreas[i+1] + rad[tool] + 1e-1)))
02541                 {
02542 
02543                     run = Detect_FeatCurve(tool);
02544 
02545                     for (int i=0; i<run; ++i)
02546                     {
02547                         ConnectPaths_Feat(tool, 1, 1);
02548                         MakePathSingle(1,0,0,tool);
02549                         ++(*it_1);
02550                     }
02551 
02552                     break;
02553                 }
02554             }
02555             else
02556             {
02557                 if (*it_2 == (*curves_2).end()-1)
02558                 {
02559                     ConnectPaths_Feat(tool, 1, 1);
02560                     MakePathSingle(1,0,0,tool);
02561                     break;
02562                 }
02563                 else break;
02564             }
02565 
02566             ConnectPaths_Feat(tool, 1, 1);
02567         }
02568 
02569         (**it_2)->D0((**it_2)->FirstParameter(),pnt0);
02570 
02571         while ((pnt0.Z() > (flatAreas[i] + rad[!tool] - 1e-1)) && 
02572                            (pnt0.Z() < (flatAreas[i] + rad[!tool] + 1e-1)))
02573         {
02574             MakePathSingle(1,0,0,!tool);
02575 
02576             if (*it_2 != (*curves_2).end()-1)
02577                 (*it_2)++;
02578             else
02579                 break;
02580 
02581             (**it_2)->D0((**it_2)->FirstParameter(),pnt0);
02582         }
02583 
02584         master_file << "output_master" << f << ".k";
02585         slave_file  << "output_slave"  << f << ".k";
02586         ++f;
02587 
02588         std::cout << master_file.str() << "  ,  " << slave_file << std::endl;
02589 
02590         anOutputFile[0].open((master_file.str()).c_str());
02591         anOutputFile[1].open((slave_file.str()).c_str());
02592 
02593         if (!tool)
02594         {
02595             anOutputFile[0] << "none" << std::endl;
02596             anOutputFile[1] << "continuous" << std::endl;
02597         }
02598         else
02599         {
02600             anOutputFile[0] << "continuous" << std::endl;
02601             anOutputFile[1] << "none" << std::endl;
02602         }
02603 
02604         WriteOutput_Feat(anOutputFile[0], anOutputFile[1],f,1);
02605 
02606         master_file.str("");
02607         master_file.clear();
02608         slave_file.str("");
02609         slave_file.clear();
02610 
02611         m_Output_robo1.clear();
02612         m_Output_robo2.clear();
02613 
02614         if (*it_1 == (*curves_1).end()-1 && *it_2 == (*curves_2).end()-1)
02615             break;
02616 
02617         ConnectPaths_Feat(0, 1, 1);
02618         ConnectPaths_Feat(1, 1, 0);
02619         ++i;
02620     }
02621 
02622     anOutputFile[0] << "*END" << endl;
02623         anOutputFile[1] << "*END" << endl;
02624     anOutputFile[0].close();
02625     anOutputFile[1].close();
02626 
02627     return true;
02628 }
02629 
02630 // Hilfsfunktion f�r den Featurebasierten Teil:
02631 // Bestimmt welches Tool wartet, w�hrend das andere l�uft
02632 bool path_simulate::StartingTool()
02633 {
02634     double z0,z1;
02635     gp_Pnt pnt0,pnt1;
02636 
02637     if(m_it1 != m_BSplineTop.end()-1)
02638     {
02639         // z-Abstand zur n�chsten Bahn - MASTER
02640         (*m_it1)->D0((*m_it1)->FirstParameter(),pnt0); m_it1++;
02641         (*m_it1)->D0((*m_it1)->FirstParameter(),pnt1); m_it1--;
02642        
02643         z0 = abs(pnt0.Z() - pnt1.Z());
02644     }
02645 
02646     else
02647         z0 = 1e+3;
02648 
02649     if(m_it2 != m_BSplineBottom.end()-1)
02650     {
02651         // z-Abstand zur n�chsten Bahn - SLAVE
02652         (*m_it2)->D0((*m_it2)->FirstParameter(),pnt0); m_it2++;
02653         (*m_it2)->D0((*m_it2)->FirstParameter(),pnt1); m_it2--;
02654         
02655         z1 = abs(pnt0.Z() - pnt1.Z());
02656     }
02657     else z1 = 1e+3;
02658 
02659     if(z0<z1)  return false;  // Slave muss warten
02660     else       return true;   // Master muss warten
02661 }
02662 
02663 /* Hier wird geschaut, ob es sich um eine geschlossene Kurve handelt bzw. wieviele Kurven abgefahren werden m�ssen
02664 um wieder am Anfangspunkt der Kurve anzukommen. Die Anzahl der zu fahrenden Kurven wird als integer zur�ckgegeben */
02665 int path_simulate::Detect_FeatCurve(bool tool)
02666 {
02667     gp_Pnt pt0,pt1;
02668     int num = 1;
02669 
02670     if(!tool)
02671         {
02672                 pt0 = (*m_it1)->StartPoint(); // Startpunkt der aktuellen Master-Kurve
02673                 pt1 = (*m_it1)->EndPoint();   // Endpunkt der aktuellen Master-Kurve
02674                 
02675                 while(pt0.Distance(pt1) > 1e-3)  // Mache weiter solange Start und Endpunkt nicht passen
02676                 {
02677                         if(m_it1 == m_BSplineTop.end()-1)  // Stoppe wenn bei der letzten Kurve angekommen
02678                         {
02679                                 for(int i=1; i<num; i++)
02680                                         m_it1--;
02681 
02682                                 num = 1;
02683                                 pt1 = pt0; // Damit die �u�ere while-Schleife verlassen wird
02684                         }
02685                         else
02686                         {
02687                                 num++;
02688                                 m_it1++;
02689                                 pt1 = (*m_it1)->EndPoint();
02690                         }
02691                 }
02692 
02693                 // Zur�ck zum Status quo
02694                 for(int i=1; i<num; i++)
02695                         m_it1--;
02696         }
02697         else
02698         {       
02699                 pt0 = (*m_it2)->StartPoint(); // Startpunkt der aktuellen Slave-Kurve
02700                 pt1 = (*m_it2)->EndPoint();   // Endpunkt der aktuellen Slave-Kurve
02701                 
02702                 while(pt0.Distance(pt1) > 1e-3) // Mache weiter solange Start und Endpunkt nicht passen
02703                 {
02704                         if(m_it2 == m_BSplineBottom.end()-1) // Stoppe wenn bei der letzten Kurve angekommen
02705                         {
02706                                 for(int i=1; i<num; i++)
02707                                         m_it2--;
02708 
02709                                 num = 1;
02710                                 pt1 = pt0;  // Damit die while-Schleife verlassen wird
02711                         }
02712                         else
02713                         {                       
02714                                 num++;
02715                                 m_it2++;
02716                                 pt1 = (*m_it2)->EndPoint();
02717                         }
02718                 }
02719 
02720                 // Zur�ck zum Status quo
02721                 for(int i=1; i<num; i++)
02722                         m_it2--;
02723         }
02724 
02725         return num;
02726 }
02727 
02728 /* Hauptroutine zur Generierung des Simulationsoutputs f�r den normalen beidseitigen Fall */
02729 bool path_simulate::MakePathSimulate()
02730 {
02731     int c1 = 1, 
02732                 c2 = 2001; 
02733 
02734     ofstream anOutputFile, anOutputFile2;
02735 
02736     anOutputFile.open("output_master.k");
02737     anOutputFile.precision(7);
02738 
02739     if (m_single == false)
02740     {
02741         anOutputFile2.open("output_slave.k");
02742         anOutputFile2.precision(7);
02743     }
02744 
02745     for (m_it1 = m_BSplineTop.begin(); m_it1 < m_BSplineTop.end(); ++m_it1)  // Schleife �ber alle Kurven 
02746     {
02747         m_StartParam[0] = ((*m_it1)->FirstParameter());     // speichert Startparameterwert der aktuellen Master-Kurve
02748        
02749                 if (m_single == false)
02750                         m_StartParam[1] = ((*m_it2)->FirstParameter()); // speichert Startparameterwert der aktuellen Slave-Kurve
02751       
02752 
02753                 /*Zustellung Start*/
02754 
02755         m_conn = CheckConnect(); // R�ckgabewert = 1 bei negativer z-Richtungszustellung
02756                                          // R�ckgabewert = 0 bei positiver z-Richtungszustellung 
02757        
02758                 //  negative z-Richtung: 1. XY --> 2. Z              
02759                 //  positive z-Richtung: 1. Z  --> 2. XY    
02760  
02761                 // *** 1. ***
02762                 if (m_conn)   ConnectPaths_xy(0);
02763         else          ConnectPaths_z(0);
02764 
02765         if (m_single == false) WriteOutputDouble(anOutputFile,anOutputFile2,c1,c2,0,beam);
02766         else                   WriteOutputSingle(anOutputFile,c1,0,0,beam);
02767 
02768         UpdateParam();
02769 
02770                 // *** 2. ***
02771         if (m_conn)   ConnectPaths_z(0);
02772         else          ConnectPaths_xy(0);
02773 
02774                 // Schreibe Output
02775         if (m_single == false) WriteOutputDouble(anOutputFile,anOutputFile2,c1,c2,0,beam);
02776         else                   WriteOutputSingle(anOutputFile,c1,0,0,beam);
02777 
02778         UpdateParam();
02779 
02780         /*Zustellung Ende*
02781                 
02782                 
02783                 /*Kurve Start*/
02784 
02785         CompPath(0); // Berechnung der Parameter f�r den Master
02786         
02787                 if (m_single == false)
02788                         CompPath(1); // Berechnung der Parameter f�r den Slave
02789 
02790                 Gen_Path();  // Erzeugung der Outputvektoren
02791 
02792                 // Schreibe Outputvektoren
02793         if (m_single == false) WriteOutputDouble(anOutputFile,anOutputFile2,c1,c2,0,beam);
02794         else                   WriteOutputSingle(anOutputFile,c1,0,0,beam);
02795 
02796         UpdateParam();
02797        
02798                 if (m_single==false && (m_it1 != (m_BSplineTop.end()-1)))
02799             ++m_it2;
02800 
02801                 /*Kurve Ende*/
02802     }
02803 
02804         //m_log.saveToFile("c:/Master-Path.iv");
02805 
02806         /*
02807         ofstream anOutputvelocity;
02808     anOutputvelocity.open("output_velocity.k");
02809     anOutputvelocity.precision(7);
02810 
02811         for(int i=0; i<(int)m_times_tmp.size(); ++i) // Schreibe absolute Geschwindigkeitswerte aus
02812                 anOutputvelocity << m_times_tmp[i] << ", " << m_velo_tmp[i] << endl;
02813         
02814         anOutputvelocity.close();
02815         */
02816 
02817     anOutputFile  << "*END" << endl;
02818     anOutputFile.close();
02819         
02820 
02821         if (m_single == false)
02822     {
02823                 anOutputFile2 << "*END" << endl;
02824         anOutputFile2.close();
02825     }
02826     
02827     // WriteTimes();
02828     return true;
02829 }
02830 
02831 /* Schreibt den Output f�r den feature- und spiral-basierten beidseitigen Fall */
02832 bool path_simulate::WriteOutput_Feat(ofstream &anOutputFile, ofstream &anOutputFile2, int &c, bool brob)
02833 {
02834     if (m_single == false)
02835     {
02836         if (brob == false)
02837         {
02838             int n = m_Output.size();
02839 
02840             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02841             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02842             anOutputFile << "2,1,0," << c <<  ",1.000000, ," << m_Output_time[n-1] << ","  << m_Output_time[0] << std::endl;
02843             anOutputFile << "*DEFINE_CURVE" << std::endl << c << std::endl;
02844 
02845             for (int i=0; i<n; ++i)
02846             {
02847                 anOutputFile << m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].x << std::endl;
02848             }
02849 
02850             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].x<< std::endl;
02851 
02852             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02853             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02854             anOutputFile << "3,1,0," << c <<  ",1.000000, ," << m_Output_time[n-1] << ","  << m_Output_time[0] << std::endl;
02855             anOutputFile << "*DEFINE_CURVE" << std::endl << c+1 << std::endl;
02856 
02857             for (int i=0; i<n; ++i)
02858             {
02859                 anOutputFile << m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][1].x << std::endl;
02860             }
02861 
02862             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][1].x<< std::endl;
02863 
02864             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02865             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02866             anOutputFile << "2,2,0," << c+1 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02867             anOutputFile << "*DEFINE_CURVE" << std::endl << c+2 << std::endl;
02868 
02869             for (int i=0; i<n; ++i)
02870             {
02871                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<< "," << m_Output[i][0].y<< std::endl;
02872             }
02873 
02874             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].y<< std::endl;
02875 
02876 
02877             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02878             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02879             anOutputFile << "3,2,0," << c+1 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02880             anOutputFile << "*DEFINE_CURVE" << std::endl << c+3 << std::endl;
02881 
02882             for (int i=0; i<n; ++i)
02883             {
02884                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<< "," << m_Output[i][1].y<< std::endl;
02885             }
02886 
02887             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][1].y<< std::endl;
02888 
02889 
02890             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02891             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02892             anOutputFile << "2,3,0," << c+2 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02893             anOutputFile << "*DEFINE_CURVE" << std::endl << c+4 <<  std::endl;
02894 
02895             for (int i=0; i<n; ++i)
02896             {
02897                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].z<< std::endl;
02898             }
02899 
02900             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].z<< std::endl;
02901 
02902 
02903             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02904             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02905             anOutputFile << "3,3,0," << c+2 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02906             anOutputFile << "*DEFINE_CURVE" << std::endl << c+5 <<  std::endl;
02907 
02908             for (int i=0; i<n; ++i)
02909             {
02910                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][1].z<< std::endl;
02911             }
02912 
02913             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][1].z<< std::endl;
02914 
02915             c = c+6;
02916         }
02917         else
02918         {
02919             int n1 = m_Output_robo1.size();
02920             for (int i=0; i<n1; ++i)
02921                 anOutputFile  << m_Output_robo1[i].x + m_set.x_offset_robot << "," <<  m_Output_robo1[i].y + m_set.y_offset_robot << "," << m_Output_robo1[i].z  << endl;
02922 
02923             anOutputFile.close();
02924 
02925             int n2 = m_Output_robo2.size();
02926             for (int i=0; i<n2; ++i)
02927                 anOutputFile2 << m_Output_robo2[i].x + m_set.x_offset_robot << "," <<  m_Output_robo2[i].y + m_set.y_offset_robot << "," << m_Output_robo2[i].z  << endl;
02928 
02929             anOutputFile2.close();
02930         }
02931     }
02932     else
02933     {
02934         if (brob == false)
02935         {
02936 
02937             int n = m_Output.size();
02938 
02939             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02940             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02941             anOutputFile << "2,1,0," << c <<  ",1.000000, ," << m_Output_time[n-1] << ","  << m_Output_time[0] << std::endl;
02942             anOutputFile << "*DEFINE_CURVE" << std::endl << c << std::endl;
02943 
02944             for (int i=0; i<n; ++i)
02945             {
02946                 anOutputFile << m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].x << std::endl;
02947             }
02948 
02949             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].x<< std::endl;
02950 
02951             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02952             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02953             anOutputFile << "2,2,0," << c+1 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02954             anOutputFile << "*DEFINE_CURVE" << std::endl << c+1 << std::endl;
02955 
02956             for (int i=0; i<n; ++i)
02957             {
02958                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<< "," << m_Output[i][0].y<< std::endl;
02959             }
02960 
02961             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].y<< std::endl;
02962 
02963             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
02964             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
02965             anOutputFile << "2,3,0," << c+2 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
02966             anOutputFile << "*DEFINE_CURVE" << std::endl << c+4 <<  std::endl;
02967 
02968             for (int i=0; i<n; ++i)
02969             {
02970                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].z<< std::endl;
02971             }
02972 
02973             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].z<< std::endl;
02974 
02975             c = c+3;
02976         }
02977         else
02978         {
02979             int n = m_Output_robo1.size();
02980 
02981             for (int i=0; i<n; ++i)
02982                 anOutputFile << m_Output_robo1[i].x << "," <<  m_Output_robo1[i].y << "," << m_Output_robo1[i].z << ",";
02983 
02984             anOutputFile << std::endl;
02985         }
02986     }
02987 
02988     return true;
02989 }
02990 
02991 /*
02992 // Schreibt alle Zeitwerte der Ausgabevektoren aus
02993 bool path_simulate::WriteTimes()
02994 {
02995     ofstream anOutputFile;
02996 
02997     anOutputFile.open("CurveTimes.k");
02998     anOutputFile.precision(7);
02999 
03000     for (unsigned int i=0; i< m_PathTimes_Master.size(); ++i)
03001     {
03002         anOutputFile << m_PathTimes_Master[i].first << " " << m_PathTimes_Master[i].second << std::endl;
03003     }
03004 
03005     for (unsigned int i=0; i< m_PathTimes_Slave.size(); ++i)
03006     {
03007         anOutputFile << m_PathTimes_Slave[i].first << " " << m_PathTimes_Slave[i].second << std::endl;
03008     }
03009 
03010     anOutputFile.close();
03011 
03012     return true;
03013 }
03014 */
03015 
03016 /* Schreibt Output f�r den normalen einseitigen Fall */
03017 bool path_simulate::WriteOutputSingle(ofstream &anOutputFile, int &c, bool brob, bool tool, bool beamfl)
03018 {
03019     std::vector< std::vector<Base::Vector3d> > Out_val;
03020     std::vector<double> Out_time;
03021     std::pair<float,float> times;
03022     int n;
03023     int ind;
03024 
03025     int pid;
03026 
03027     if (brob == true)  // Schreibe Roboter-Output
03028         {
03029                 std::vector<Base::Vector3d> Out_rob;
03030 
03031                 if (!tool) Out_rob  = m_Output_robo1;
03032                 else       Out_rob  = m_Output_robo2;
03033 
03034                 n = Out_rob.size();
03035 
03036                 for (int i=0; i<n; ++i)
03037                         anOutputFile << Out_rob[i].x + m_set.x_offset_robot << "," <<  Out_rob[i].y + m_set.y_offset_robot << "," << Out_rob[i].z << "," << std::endl;
03038 
03039                 anOutputFile << std::endl;
03040                 return true;
03041         }
03042 
03043         if (!tool)
03044     {
03045         Out_val  = m_Output;
03046         Out_time = m_Output_time;
03047         ind = 2;
03048     }
03049     else
03050     {
03051         Out_val  = m_Output2;
03052         Out_time = m_Output_time2;
03053         ind = 3;
03054     }
03055 
03056     if (beamfl && tool) pid = ind+1;    // pid: 2 - Master
03057     else                pid = ind;      //      3 - Slave
03058                                         //      4 - Plate (x-,y-movement) 
03059 
03060     n = Out_val.size();
03061 
03062     if (n != Out_time.size())
03063         throw Base::Exception("Outputl�ngen passen nicht zusammen");
03064 
03065     if (n>1)
03066     {
03067         anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03068         anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03069         anOutputFile << ind << ",1,0," << c <<  ",1.000000, ," << Out_time[n-1] << ","  << Out_time[0] << std::endl;
03070         
03071 
03072                 if (beamfl && tool)
03073         {
03074             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03075                         anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03076                         anOutputFile << pid << ",1,0," << c <<  ",1.000000, ," << Out_time[n-1] << ","  << Out_time[0] << std::endl;
03077         }
03078                 
03079                 anOutputFile << "*DEFINE_CURVE" << std::endl << c << std::endl;
03080 
03081         for (int i=0; i<n; ++i)
03082         {
03083             anOutputFile << Out_time[i] - Out_time[0]<<"," << Out_val[i][0].x << std::endl;
03084         }
03085 
03086         anOutputFile << Out_time[n-1] - Out_time[0] + 0.1 << "," << Out_val[n-1][0].x << std::endl;
03087 
03088         times.first  = (float) Out_time[0];
03089         times.second = (float) Out_time[n-1];
03090 
03091         if (!tool) m_PathTimes_Master.push_back(times);
03092         else      m_PathTimes_Slave.push_back(times);
03093 
03094         anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03095         anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03096         anOutputFile << ind << ",2,0," << c+1 <<  ",1.000000, ," << Out_time[n-1] << "," << Out_time[0] << std::endl;
03097         
03098 
03099                 if (beamfl && tool)
03100         {
03101             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03102                         anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03103                         anOutputFile << pid << ",2,0," << c+1 <<  ",1.000000, ," << Out_time[n-1] << "," << Out_time[0] << std::endl;
03104         }
03105                 
03106                 anOutputFile << "*DEFINE_CURVE" << std::endl << c+1 << std::endl;
03107 
03108         for (int i=0; i<n; ++i)
03109         {
03110             anOutputFile <<  Out_time[i] - Out_time[0]<< "," << Out_val[i][0].y << std::endl;
03111         }
03112 
03113         anOutputFile << Out_time[n-1] - Out_time[0] + 0.1 << "," << Out_val[n-1][0].y << std::endl;
03114 
03115         times.first  = (float) Out_time[0];
03116         times.second = (float) Out_time[n-1];
03117 
03118         if (!tool) m_PathTimes_Master.push_back(times);
03119         else      m_PathTimes_Slave.push_back(times);
03120 
03121         if (beamfl && tool)
03122         {
03123                         anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03124             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03125             anOutputFile << pid << ",3,0," << c+2 <<  ",1.000000, ," << Out_time[n-1] << "," << Out_time[0] << std::endl;
03126         }
03127                 else
03128                 {
03129                         anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03130                         anOutputFile << "$#     ind       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03131                         anOutputFile << ind << ",3,0," << c+2 <<  ",1.000000, ," << Out_time[n-1] << "," << Out_time[0] << std::endl;
03132                 }
03133 
03134         anOutputFile << "*DEFINE_CURVE" << std::endl << c+2 <<  std::endl;
03135 
03136 
03137         for (int i=0; i<n; ++i)
03138         {
03139             anOutputFile <<  Out_time[i] - Out_time[0]<<"," << Out_val[i][0].z<< std::endl;
03140         }
03141 
03142         anOutputFile << Out_time[n-1] - Out_time[0] + 0.1 << "," << Out_val[n-1][0].z<< std::endl;
03143 
03144         times.first  = (float) Out_time[0];
03145         times.second = (float) Out_time[n-1];
03146 
03147         if (!tool) m_PathTimes_Master.push_back(times);
03148         else       m_PathTimes_Slave.push_back(times);
03149 
03150         c = c+3;
03151     }
03152 
03153     return true;
03154 }
03155 
03156 /* Schreibt Output f�r den normalen beidseitigen Fall */
03157 bool path_simulate::WriteOutputDouble(ofstream &anOutputFile, ofstream &anOutputFile2, int &c1, int &c2, bool brob, bool beamfl)
03158 {
03159     std::pair<float,float> times;
03160     int pid1 = 2; // Master
03161         int pid2 = 3; // Slave
03162         int pid3 = 4; // Platte
03163 
03164     if (brob == false) // Simulations-Output (brob == true -> roboter-ouput)
03165     {
03166                 TimeCorrection();
03167 
03168         int n = m_Output.size();   // Master
03169         int n2 = m_Output2.size(); // Slave
03170 
03171         if (n>1)
03172         {
03173 
03174             // MASTER-X
03175 
03176             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03177             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03178             anOutputFile << pid1 << ",1,0," << c1 <<  ",1.000000, ," << m_Output_time[n-1] << ","  << m_Output_time[0] << std::endl;
03179             anOutputFile << "*DEFINE_CURVE" << std::endl << c1 << std::endl;
03180 
03181             for (int i=0; i<n; ++i)
03182             {
03183                 anOutputFile << m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].x << std::endl;
03184             }
03185 
03186             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].x << std::endl;
03187 
03188             times.first  = (float) m_Output_time[0];
03189             times.second = (float) m_Output_time[n-1];
03190             m_PathTimes_Master.push_back(times);       // f�lle vektor f�r curve-times
03191 
03192             
03193                         
03194                         
03195                         // SLAVE-X
03196 
03197             anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03198             anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03199             anOutputFile2 << pid2 << ",1,0," << c2 <<  ",1.000000, ," << m_Output_time2[n2-1] << ","  << m_Output_time2[0] << std::endl;
03200                         
03201                         if (beamfl) // wenn auf true, dann f�ge neuen part mit ein
03202             {
03203                 anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03204                 anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03205                 anOutputFile2 << pid3 << ",1,0," << c2<<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
03206             }
03207 
03208                         anOutputFile2 << "*DEFINE_CURVE" << std::endl << c2 << std::endl;
03209 
03210             for (int i=0; i<n2; ++i)
03211             {
03212                 anOutputFile2 << m_Output_time2[i] - m_Output_time2[0]<<"," << m_Output2[i][0].x << std::endl;
03213             }
03214 
03215             anOutputFile2 << m_Output_time2[n2-1] - m_Output_time2[0] + 0.1 << "," << m_Output2[n2-1][0].x << std::endl;
03216 
03217             times.first  = (float) m_Output_time2[0];
03218             times.second = (float) m_Output_time2[n2-1];
03219             m_PathTimes_Slave.push_back(times);
03220 
03221             
03222                         
03223                         
03224                         
03225                         // MASTER-Y
03226 
03227             anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03228             anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03229             anOutputFile << pid1 << ",2,0," << c1+1 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
03230             anOutputFile << "*DEFINE_CURVE" << std::endl << c1+1 << std::endl;
03231 
03232             for (int i=0; i<n; ++i)
03233             {
03234                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<< "," << m_Output[i][0].y << std::endl;
03235             }
03236 
03237             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].y << std::endl;
03238 
03239             times.first  = (float) m_Output_time[0];
03240             times.second = (float) m_Output_time[n-1];
03241             m_PathTimes_Master.push_back(times);
03242 
03243             
03244                         
03245                         
03246                         // SLAVE-Y
03247 
03248             anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03249             anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03250             anOutputFile2 << pid2 << ",2,0," << c2+1 <<  ",1.000000, ," << m_Output_time2[n2-1] << ","  << m_Output_time2[0] << std::endl;
03251             
03252                         if (beamfl) // wenn auf true, dann f�ge neuen part mit ein
03253             {
03254                 anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03255                 anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03256                 anOutputFile2 << pid3 << ",2,0," << c2+1 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
03257             }
03258                         
03259                         anOutputFile2 << "*DEFINE_CURVE" << std::endl << c2+1 << std::endl;
03260 
03261             for (int i=0; i<n2; ++i)
03262             {
03263                 anOutputFile2 << m_Output_time2[i] - m_Output_time2[0]<<"," << m_Output2[i][0].y << std::endl;
03264             }
03265 
03266             anOutputFile2 << m_Output_time2[n2-1] - m_Output_time2[0] + 0.1 << "," << m_Output2[n2-1][0].y << std::endl;
03267 
03268             times.first  = (float) m_Output_time2[0];
03269             times.second = (float) m_Output_time2[n2-1];
03270             m_PathTimes_Slave.push_back(times);
03271 
03272             
03273                         
03274                         
03275                         
03276                         // MASTER-Z
03277                         anOutputFile << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03278                         anOutputFile << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03279                         anOutputFile << pid1 << ",3,0," << c1+2 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
03280             anOutputFile << "*DEFINE_CURVE" << std::endl << c1+2 <<  std::endl;
03281 
03282 
03283             for (int i=0; i<n; ++i)
03284             {
03285                 anOutputFile <<  m_Output_time[i] - m_Output_time[0]<<"," << m_Output[i][0].z<< std::endl;
03286             }
03287 
03288             anOutputFile << m_Output_time[n-1] - m_Output_time[0] + 0.1 << "," << m_Output[n-1][0].z<< std::endl;
03289 
03290             times.first  = (float) m_Output_time[0];
03291             times.second = (float) m_Output_time[n-1];
03292             m_PathTimes_Master.push_back(times);
03293 
03294 
03295                         
03296                         // SLAVE-Z
03297 
03298                         if (beamfl)
03299             {
03300                 anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03301                 anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03302                 anOutputFile2 << pid3 << ",3,0," << c2+2 <<  ",1.000000, ," << m_Output_time[n-1] << "," << m_Output_time[0] << std::endl;
03303 
03304             }
03305                         else
03306                         {
03307                                 anOutputFile2 << "*BOUNDARY_PRESCRIBED_MOTION_RIGID" << std::endl;
03308                                 anOutputFile2 << "$#     pid       dof       vad      lcid        sf       vid     death     birth" << std::endl;
03309                                 anOutputFile2 << pid2 << ",3,0," << c2+2 <<  ",1.000000, ," << m_Output_time2[n2-1] << ","  << m_Output_time2[0] << std::endl;
03310                         }
03311 
03312             anOutputFile2 << "*DEFINE_CURVE" << std::endl << c2+2 <<  std::endl;
03313 
03314             for (int i=0; i<n2; ++i)
03315             {
03316                 anOutputFile2 << m_Output_time2[i] - m_Output_time2[0]<<"," << m_Output2[i][0].z << std::endl;
03317             }
03318 
03319             anOutputFile2 << m_Output_time2[n2-1] - m_Output_time2[0] + 0.1 << "," << m_Output2[n2-1][0].z << std::endl;
03320 
03321             times.first  = (float) m_Output_time2[0];
03322             times.second = (float) m_Output_time2[n2-1];
03323             m_PathTimes_Slave.push_back(times);
03324 
03325             c1 += 3;
03326             c2 += 3;
03327         }
03328     }
03329     else  // Schreibe Roboter-Output
03330     {
03331             int n1 = m_Output_robo1.size();
03332             for (int i=0; i<n1; ++i)
03333                 anOutputFile  << m_Output_robo1[i].x + m_set.x_offset_robot << "," <<  m_Output_robo1[i].y + m_set.y_offset_robot << "," << m_Output_robo1[i].z << "," << RoboFlag_Master[i] << endl;
03334 
03335             int n2 = m_Output_robo2.size();
03336             for (int i=0; i<n2; ++i)
03337                 anOutputFile2 << m_Output_robo2[i].x + m_set.x_offset_robot << "," <<  m_Output_robo2[i].y + m_set.y_offset_robot << "," << m_Output_robo2[i].z << "," << RoboFlag_Slave[i] << endl;
03338     }
03339 
03340     return true;
03341 }

Generated on Wed Nov 23 19:00:26 2011 for FreeCAD by  doxygen 1.6.1