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