File: MANJUST\MJ_FUNK.CPP

    1 //#############################################################################
    2 //                                                                           //
    3 // MJ_FUNK.CPP                                                               //
    4 //                                                                           //
    5 // Subsystem : neue Manuelle Justage / Funktionalität                        //
    6 // Benutzung durch andere Subsysteme erforderlich: NEIN                      //
    7 //---------------------------------------------------------------------------//
    8 // Autoren:  Thomas Kullmann, Günther Reinecker                              //
    9 // Stand  : 23.11.2002                                                       //
   10 //                                                                           //
   11 //#############################################################################
   12 
   13 #include "utils\u_utils.h"
   14 #include <assert.h> // ::assert()
   15 
   16 #include "manjust\mj_funk.h" // SCHNITTSTELLE für diese Datei
   17 
   18 #include "datavisa\datavisa.h" // "difrkmty.h"
   19 //#include "difrkmty\difrkmty.h" // TOneDimDetector
   20 #include "workflow\workflow.h" // extern Steering
   21 
   22 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   23 
   24 //##############################################################################
   25 // externe Abhängigkeiten
   26 //##############################################################################
   27 
   28 extern TSteering Steering;
   29 __declspec(dllimport) LPMList lpMList; //Komposition aus TMotor-Objekten
   30 
   31 //##############################################################################
   32 // TManJustage
   33 //##############################################################################
   34 
   35 //------------------------------------------------------------------------------
   36 // Konstruktor / Destruktor
   37 //------------------------------------------------------------------------------
   38 TManJustage::TManJustage ( void ) : m_MotorList(0)
   39 {
   40         TMotor *Mtr;
   41         BOOL bValid;
   42 
   43         m_MotorCount= lpMList->GetAxisNumber(); // Anzahl der Motoren in lpMList
   44         m_MotorList= new TMotorData[ GetMotorCount() ];
   45         for ( UINT i= 0; i < GetMotorCount(); i++ )
   46         {
   47                 Mtr= lpMList->MP( i );
   48                 assert( Mtr ); // Motorliste muss stehts gültiges Motorobjekt zurückgeben
   49                 m_MotorList[i].m_lnkMotor= Mtr;
   50                 m_MotorList[i].m_AxisType= lpMList->ParsingAxis( Mtr->pCharacteristic() );
   51                 sprintf( m_MotorList[i].m_MotorId, "motor%d", Mtr->GetId() ); // Index der ini-Sektion
   52                 // die zuletzt verwendete Betriebsart;
   53                 LONG idx= IniReadLong( GetHWFile(), m_MotorList[i].m_MotorId, "MJ_MotionType", 0 );
   54                 if ( idx == 1 )
   55                         m_MotorList[i].m_MotionType= mtDrive;
   56                 else if ( idx == 2 )
   57                         m_MotorList[i].m_MotionType= mtStep;
   58                 else
   59                         m_MotorList[i].m_MotionType= mtDirect; // default
   60                 // die zuletzt verwendeten Betriebsparameter & Offset
   61                 m_MotorList[i].m_AngleDest= IniReadDouble( GetHWFile(), m_MotorList[i].m_MotorId, "MJ_AngleDest", GetAngleMin(i, bValid), 0, GetAngleMax(i, bValid), GetDigits(i, bValid) ); // SollPos
   62                 m_MotorList[i].m_Speed= IniReadDouble( GetHWFile(), m_MotorList[i].m_MotorId, "MJ_Speed", 0, Mtr->GetSpeed(), Mtr->GetMaxSpeed(), GetDigits(i, bValid) ); // Geschw.
   63                 m_MotorList[i].m_AngleWidth= IniReadDouble( GetHWFile(), m_MotorList[i].m_MotorId, "MJ_AngleWidth", Mtr->GetMinAngleWidth(), Mtr->GetMinAngleWidth(), ( fabs(GetAngleMin(i, bValid)) + GetAngleMax(i, bValid) ), GetDigits(i, bValid) + 1 ); // Schrittweite
   64                 Mtr->SetAngleBias( IniReadDouble( GetHWFile(), m_MotorList[i].m_MotorId, "MJ_Offset", -10000.0, 0.0, +10000.0, GetDigits(i, bValid) ) ); // Offset (keine Intervallgrenzen)
   65                 // derzeit nicht in Bewegung
   66                 m_MotorList[i].m_KzMoving= FALSE;
   67                 // Kennzeichnen, dass bislang keine Daten zwischengespeichert werden
   68                 m_MotorList[i].m_SpAngle= 0;  
   69                 m_MotorList[i].m_HasAngle= FALSE; 
   70                 m_MotorList[i].m_SpMoving= FALSE;  
   71                 m_MotorList[i].m_HasMoving= FALSE; 
   72         }
   73         // erst danach darf der Detektor initialisiert werden
   74         TDetector *actDetector= TDetectorManager::DetectorManager().GetDetector(0, 1); // Detektor für PSD-Offset
   75         if ( (actDetector) && (actDetector->GetDimension() == 1) && (actDetector->GetDetectorType() == PsdDetector))
   76         {
   77                 m_lnkDetector= dynamic_cast<TOneDimDetector*>(actDetector); // muss eindimensional sein
   78                 sprintf( m_DetectorId, "device%d", m_lnkDetector->GetId() ); // Index der ini-Sektion
   79                 m_Channel= IniReadLong( GetHWFile(), m_DetectorId, "MJ_Channel", m_lnkDetector->GetFirstChannel(), m_lnkDetector->GetFirstChannel(), m_lnkDetector->GetLastChannel() ); // KanalOffset (keinesfalls SetChannel verwenden, weil dies Rückwirkungen auf AngleBias hätte)
   80         }
   81         else 
   82         { // keine ausgewählter Detektor oder Detektor ist nicht eindimensional
   83                 m_lnkDetector= 0; 
   84                 strcpy(m_DetectorId, "");
   85                 m_Channel= 0;
   86         }
   87         m_IsMeasuring= FALSE; // Halbwertsbreitenmessung wurde nicht von uns gestartet
   88         m_KzMeasuring= FALSE;
   89         // Speeding derzeit nicht aktiv
   90         m_UpdateCount= 0;
   91 };
   92 //----------------------------------------------------------------------------------------
   93 // Destruktor
   94 
   95 TManJustage::~TManJustage ( void )
   96 {
   97         _FREELIST( m_MotorList );
   98 };
   99 //----------------------------------------------------------------------------------------
  100 // Antriebssteuerung
  101 //----------------------------------------------------------------------------------------
  102 // Bewegung im Direktbetrieb
  103 
  104 BOOL TManJustage::DoDirect ( const int aIndex )
  105 {
  106         if ( !CanDoDirect( aIndex ) )
  107                 return FALSE; // Direktbetrieb kann nicht durchgeführt werden
  108 
  109         TMotor *Mtr= m_MotorList[aIndex].m_lnkMotor;
  110         BOOL bValid= FALSE;
  111         Mtr->SetSpeed( GetSpeed(aIndex, bValid) );  // akt. Geschw. setzen
  112         Mtr->ActivateDrive(); //Antrieb aktivieren
  113         if ( (!bValid) || (!Mtr->MoveToAngle( GetAngleDest(aIndex, bValid) )) )
  114                 return FALSE; // anfahren der Sollposition
  115         // nicht MtrData->m_KzMoving auf TRUE setzen, sonst wird dies TManJustageDlg::OnMotionStarts vorweggeriffen
  116         return TRUE;
  117 };
  118 //----------------------------------------------------------------------------------------
  119 // Bewegung im Fahrbetrieb
  120 
  121 BOOL TManJustage::DoDrive ( const int aIndex, const EDirection aDirection )
  122 {
  123         if ( !CanDoDrive( aIndex, aDirection ) )
  124                 return FALSE; // Fahrbetrieb kann nicht durchgeführt werden
  125 
  126         TMotor *Mtr= m_MotorList[aIndex].m_lnkMotor;
  127         BOOL bValid= FALSE;
  128 
  129         Mtr->SetSpeed( GetSpeed(aIndex, bValid) );
  130         Mtr->ActivateDrive(); //Antrieb aktivieren
  131         // zur maximalen Antriebsposition bewegen
  132         if ( (aDirection == dUp) && (!Mtr->MoveToAngle( GetAngleMax(aIndex, bValid) )) )
  133                 return FALSE; // Motor konnte nicht gestartet werden
  134         // zur minimalen Antriebsposition bewegen
  135         if ( (aDirection == dDown) && (!Mtr->MoveToAngle( GetAngleMin(aIndex, bValid) )) )
  136                 return FALSE; // Motor konnte nicht gestartet werden
  137         // nicht MtrData->m_KzMoving auf TRUE setzen, sonst wird dies TManJustageDlg::OnMotionStarts vorweggeriffen
  138         return TRUE;
  139 };
  140 //----------------------------------------------------------------------------------------
  141 // Bewegung im Schrittbetrieb
  142 
  143 BOOL TManJustage::DoStep ( const int aIndex, const EDirection aDirection )
  144 {
  145         if ( !CanDoStep( aIndex, aDirection ) )
  146                 return FALSE;  // Schrittbetrieb kann nicht durchgeführt werden
  147 
  148         TMotor *Mtr= m_MotorList[aIndex].m_lnkMotor;
  149         BOOL bValid= FALSE;
  150         Mtr->SetSpeed( Mtr->GetMaxSpeed() );  // akt. Geschw. soll maximal sein
  151         TAngle AngleWidth= GetAngleWidth(aIndex, bValid);
  152         if ( !bValid )
  153                 return FALSE;  // lesen der Schrittweite ist fehlgeschlagen
  154 
  155         Mtr->ActivateDrive(); //Antrieb aktivieren
  156         // zu <aktuelle Position> + <Schrittweite> bewegen
  157         if (( aDirection == dUp ) && ( !Mtr->MoveByAngle( AngleWidth ) ))
  158                 return FALSE; // Motor konnte nicht gestartet werden
  159         // zu <aktuelle Position> - <Schrittweite> bewegen
  160         if (( aDirection == dDown ) && ( !Mtr->MoveByAngle( -AngleWidth ) ))
  161                 return FALSE; // Motor konnte nicht gestartet werden
  162         // nicht MtrData->m_KzMoving auf TRUE setzen, sonst wird dies TManJustageDlg::OnMotionStarts vorweggeriffen
  163         return TRUE;
  164 };
  165 //----------------------------------------------------------------------------------------
  166 // Stoppen der Bewegung, unabhängig von der Betriebsart
  167 
  168 BOOL TManJustage::DoStop ( const int aIndex )
  169 {
  170         if ( !CanDoStop( aIndex ) )
  171                 return FALSE; // Bewegung kann nicht gestoppt werden
  172 
  173         TMotor *Mtr= m_MotorList[aIndex].m_lnkMotor;
  174         Mtr->StopDrive( TRUE ); //restartable
  175         // nicht MtrData->m_KzMoving auf FALSE setzen, sonst wird dies TManJustageDlg::OnMotionStops vorweggeriffen
  176         return TRUE;
  177 };
  178 //----------------------------------------------------------------------------------------
  179 // Stoppen aller Antriebe, der Halbwertsbreitenmessung und der Detektormessung
  180 
  181 void TManJustage::DoStopEverything ( void ) 
  182 {
  183         //zuerst die Halbwertsbreitenmessung stoppen
  184         DoStopMeasure();
  185         //Detektor neu starten
  186         TDetector *Detector= GetDetector();
  187         if ( Detector ) 
  188   {
  189                 Detector->MeasureStop();
  190                 Detector->PopSettings();
  191                 Detector->MeasureStart();
  192         };
  193         //letztendlich auch die Antriebe stoppen
  194         for (UINT i= 0; i < GetMotorCount(); i++) 
  195   {
  196                 TMotor *Mtr= m_MotorList[i].m_lnkMotor;
  197                 Mtr->SetCorrectionState( FALSE );
  198                 DoStop(i);
  199         };
  200 };
  201 //----------------------------------------------------------------------------------------
  202 // Statusinformationen
  203 //----------------------------------------------------------------------------------------
  204 // Test ob Index im Intervall
  205 
  206 BOOL TManJustage::IsIndexValid ( const int aIndex ) const 
  207 {
  208         return ( (0 <= aIndex) && (aIndex < (int)GetMotorCount()) );
  209 };
  210 //----------------------------------------------------------------------------------------
  211 // Status des Offset für <Antrieb>
  212 
  213 BOOL TManJustage::HasOffset ( const int aIndex, BOOL &aValid ) const 
  214 {
  215         aValid= FALSE;
  216         if ( !IsIndexValid ( aIndex ) )
  217                 return FALSE;
  218 
  219         aValid= TRUE;
  220         return m_MotorList[aIndex].m_lnkMotor->IsDistanceRelative();
  221 };
  222 //----------------------------------------------------------------------------------------
  223 // Status der Bewegung
  224 
  225 BOOL TManJustage::IsMoving ( const int aIndex, BOOL &aValid ) 
  226 {
  227         if (m_UpdateCount>0) { // Speeding
  228                 aValid= FALSE;
  229                 if ( !IsIndexValid ( aIndex ) )
  230                         return FALSE;
  231 
  232                 // wenn nötig versuchen Antriebsstatus zwischenspeichern
  233                 if ( !m_MotorList[aIndex].m_HasMoving ) 
  234                 {
  235                         m_MotorList[aIndex].m_SpMoving= DetermineMoving( aIndex, aValid );
  236                         m_MotorList[aIndex].m_HasMoving= aValid;
  237                 }
  238                 // wenn möglich diesen zwischengespeicherten Antriebsstatus benutzen
  239                 if ( m_MotorList[aIndex].m_HasMoving ) 
  240                 {
  241                         aValid= TRUE;
  242                         return m_MotorList[aIndex].m_SpMoving;
  243                 }
  244         }
  245         return DetermineMoving( aIndex, aValid );
  246 };
  247 //----------------------------------------------------------------------------------------
  248 // Antrieb kalibriert?
  249 
  250 BOOL TManJustage::IsCalibrated ( const int aIndex, BOOL &aValid ) const 
  251 {
  252         aValid= FALSE;
  253         if ( !IsIndexValid (aIndex) )
  254                 return FALSE;
  255 
  256         aValid= TRUE;
  257         return ( m_MotorList[aIndex].m_lnkMotor->IsCalibrated() );
  258 };
  259 //----------------------------------------------------------------------------------------
  260 // GET-Methoden
  261 //----------------------------------------------------------------------------------------
  262 // Betriebsart
  263 
  264 EMotionType TManJustage::GetMotionType ( const int aIndex, BOOL& aValid) const
  265 {
  266         aValid= FALSE;
  267         if ( !IsIndexValid ( aIndex ) )
  268                 return mtDirect;
  269 
  270         aValid= TRUE;
  271         return m_MotorList[aIndex].m_MotionType; // lokalen Wert zurückgeben
  272 };
  273 //----------------------------------------------------------------------------------------
  274 // Sollposition
  275 
  276 TAngle TManJustage::GetAngleDest ( const int aIndex, BOOL &aValid) const
  277 {
  278         aValid= FALSE;
  279         if ( !IsIndexValid ( aIndex ) )
  280                 return FALSE;
  281 
  282         TMotorData *MtrData= &m_MotorList[aIndex];
  283   TAngle result= MtrData->m_AngleDest;
  284   TMotor *Mtr= MtrData->m_lnkMotor;
  285   SetInRange( result, Mtr->GetAngleRelativeMin(), Mtr->GetAngleRelativeMax() ); // Anpassung an Intervallgrenzen
  286   aValid= TRUE;
  287   return result; // lokalen Wert zurückgeben
  288 };
  289 //----------------------------------------------------------------------------------------
  290 // Geschwindigkeit
  291 
  292 TSpeed TManJustage::GetSpeed ( const int aIndex, BOOL &aValid ) const
  293 {
  294         aValid= FALSE;
  295         if ( !IsIndexValid ( aIndex ) )
  296                 return FALSE;
  297 
  298         aValid= TRUE;
  299         return m_MotorList[aIndex].m_Speed; // lokalen Wert zurückgeben
  300 };
  301 //----------------------------------------------------------------------------------------
  302 // Schrittweite
  303 
  304 TAngle TManJustage::GetAngleWidth ( const int aIndex, BOOL &aValid ) const
  305 {
  306         aValid= FALSE;
  307         if ( !IsIndexValid ( aIndex ) )
  308                 return FALSE;
  309 
  310   aValid= TRUE;
  311   return m_MotorList[aIndex].m_AngleWidth; // lokalen Wert zurückgeben (muss nicht an Intervallgrenzen angepasst werden, weil sich diese nicht ändern; Anpassung kann bei SetAngleWidth erfolgen)
  312 };
  313 //----------------------------------------------------------------------------------------
  314 // OnTimer() will auf Start/ Stop der Bewegung reagieren
  315 
  316 BOOL TManJustage::GetKzMoving ( const int aIndex, BOOL &aValid ) const
  317 {
  318         aValid= FALSE;
  319         if ( !IsIndexValid ( aIndex ) )
  320                 return FALSE;
  321 
  322         aValid= TRUE;
  323         return m_MotorList[aIndex].m_KzMoving; // lokalen Wert zurückgeben
  324 };
  325 //----------------------------------------------------------------------------------------
  326 // Istposition als Winkelangabe
  327 
  328 TAngle TManJustage::GetAngle ( const int aIndex, BOOL &aValid )
  329 {
  330         if ( m_UpdateCount>0 ) { // Speeding
  331                 aValid= FALSE;
  332                 if ( !IsIndexValid ( aIndex ) )
  333                         return FALSE;
  334 
  335                 // wenn nötig versuchen letzte Antriebsposition zwischenspeichern
  336                 if ( !m_MotorList[aIndex].m_HasAngle ) 
  337                 {
  338                         m_MotorList[aIndex].m_SpAngle= DetermineAngle( aIndex, aValid );
  339                         m_MotorList[aIndex].m_HasAngle= aValid;
  340 
  341                 }
  342                 // wenn möglich diese zwischengespeicherte letzte Antriebsposition benutzen
  343                 if ( m_MotorList[aIndex].m_HasAngle ) 
  344                 {
  345                         aValid= TRUE;
  346                         return m_MotorList[aIndex].m_SpAngle;
  347                 }
  348         }
  349         return DetermineAngle( aIndex, aValid );
  350 };
  351 //----------------------------------------------------------------------------------------
  352 // Minimalposition als Winkelangabe
  353 
  354 TAngle TManJustage::GetAngleMin ( const int aIndex, BOOL &aValid ) const
  355 {
  356         aValid= FALSE;
  357         if ( !IsIndexValid ( aIndex ) )
  358                 return 0.0;
  359 
  360         aValid= TRUE;
  361         return min( m_MotorList[aIndex].m_lnkMotor->GetAngleRelativeMin(),   // 22.01.2003: auch Zahlendreher in ini-Datei unterstützen
  362                                 m_MotorList[aIndex].m_lnkMotor->GetAngleRelativeMax() );
  363 };
  364 //----------------------------------------------------------------------------------------
  365 // Maximalposition als Winkelangabe
  366 
  367 TAngle TManJustage::GetAngleMax ( const int aIndex, BOOL &aValid ) const
  368 {
  369         aValid= FALSE;
  370         if ( !IsIndexValid ( aIndex ) )
  371                 return 0.0;
  372 
  373         aValid= TRUE;
  374         return max( m_MotorList[aIndex].m_lnkMotor->GetAngleRelativeMin(),   // 22.01.2003: auch Zahlendreher in ini-Datei unterstützen
  375                                 m_MotorList[aIndex].m_lnkMotor->GetAngleRelativeMax() );
  376 };
  377 //----------------------------------------------------------------------------------------
  378 // Nachkommastellen
  379 
  380 UINT TManJustage::GetDigits ( const int aIndex, BOOL &aValid ) const
  381 {
  382         aValid= FALSE;
  383         if ( !IsIndexValid ( aIndex ) )
  384                 return 2;
  385 
  386         aValid= TRUE;
  387         return m_MotorList[aIndex].m_lnkMotor->GetDigits();
  388 };
  389 //----------------------------------------------------------------------------------------
  390 // Einheit des Antriebs
  391 
  392 LPCSTR TManJustage::GetUnit ( const int aIndex, BOOL &aValid ) const
  393 {
  394         aValid= FALSE;
  395         if ( !IsIndexValid ( aIndex ) )
  396                 return "";
  397 
  398         aValid= TRUE;
  399         return m_MotorList[aIndex].m_lnkMotor->GetUnitName();
  400 };
  401 //----------------------------------------------------------------------------------------
  402 // Anzahl der Antriebe in der Antriebsliste
  403 
  404 UINT TManJustage::GetMotorCount ( void ) const
  405 {
  406         return m_MotorCount;
  407 };
  408 //----------------------------------------------------------------------------------------
  409 // Zeiger auf einen Eintrag in der Motorenliste
  410 
  411 LPCSTR TManJustage::GetMotorName ( const int aIndex, BOOL &aValid ) const
  412 {
  413         aValid= FALSE;
  414         if ( !IsIndexValid ( aIndex ) )
  415                 return "";
  416 
  417         aValid= TRUE;
  418         return m_MotorList[aIndex].m_lnkMotor->pCharacteristic();
  419 };
  420 //----------------------------------------------------------------------------------------
  421 // Index des angegebenen Antriebs; ggf. -1
  422 
  423 int TManJustage::GetMotorIdx ( const LPCSTR aName ) const
  424 {
  425         BOOL bValid;
  426         for (UINT i= 0; i < GetMotorCount(); i++)
  427                 if ( (strcmp( aName, GetMotorName(i, bValid)) == 0) && (bValid) )
  428                         return i;
  429         return -1; // nicht gefunden
  430 }
  431 //----------------------------------------------------------------------------------------
  432 // Index des angegebenen Antriebs; ggf. -1
  433 
  434 int TManJustage::GetMotorIdx ( const EAxisType aAxisType ) const
  435 {
  436         if ( aAxisType == (EAxisType)0 )
  437                 return -1; // kann nicht eindeutig identifiziert werden
  438         for (UINT i= 0; i < GetMotorCount(); i++)
  439                 if ( m_MotorList[i].m_AxisType == aAxisType )
  440                         return i;
  441         return -1; // nicht gefunden
  442 };
  443 //----------------------------------------------------------------------------------------
  444 // Antrieb der zur Halbwertsbreitenmessung verwendet wird
  445 EAxisType TManJustage::GetHwbAxis() 
  446 { 
  447         if ( GetMotorIdx(DF) != -1 ) return DF;
  448         else if ( GetMotorIdx(Omega) != -1 ) return Omega;
  449         else return EAxisType(0);
  450 }
  451 
  452 //----------------------------------------------------------------------------------------
  453 // standardisierte Antriebsbezeichnung
  454 
  455 UINT TManJustage::ParsingAxis ( const LPCSTR aCharacteristic )
  456 {
  457         return TMList::ParsingAxis( aCharacteristic );
  458 };
  459 //----------------------------------------------------------------------------------------
  460 // SET-Methoden
  461 //----------------------------------------------------------------------------------------
  462 // Betriebsart
  463 
  464 BOOL TManJustage::SetMotionType ( const int aIndex, EMotionType &aMotionType )
  465 {
  466         if ( !CanSetMotionType( aIndex ) )
  467                 return FALSE; // Betriebsart kann nicht gesetzt werden
  468 
  469         TMotorData *MtrData= &m_MotorList[aIndex];
  470         LONG idx;
  471         if ( aMotionType == mtDrive )
  472                 idx= 1;
  473         else if ( aMotionType == mtStep )
  474                 idx= 2;
  475         else
  476                 idx= 0; // mtDirect
  477         IniWriteLong( GetHWFile(), MtrData->m_MotorId, "MJ_MotionType", idx );
  478         MtrData->m_MotionType= aMotionType; // lokal setzen
  479         return TRUE;
  480 };
  481 //----------------------------------------------------------------------------------------
  482 // Sollposition
  483 
  484 BOOL TManJustage::SetAngleDest ( const int aIndex, TAngle& aAngleDest )
  485 {
  486         BOOL bValid= FALSE;
  487         if ( !CanSetAngleDest( aIndex ) )
  488                 return FALSE; // Sollposition kann nicht gesetzt werden
  489 
  490         TMotorData *MtrData= &m_MotorList[aIndex];
  491         TMotor *Mtr= MtrData->m_lnkMotor;
  492         SetInRange( aAngleDest, Mtr->GetAngleRelativeMin(), Mtr->GetAngleRelativeMax() ); // Anpassung an Intervallgrenzen
  493         MtrData->m_AngleDest= aAngleDest; // lokal setzen
  494         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_AngleDest", aAngleDest, GetDigits(aIndex, bValid) );
  495         return bValid;
  496 };
  497 //----------------------------------------------------------------------------------------
  498 // Geschwindigkeit
  499 
  500 BOOL TManJustage::SetSpeed ( const int aIndex, TSpeed &aSpeed )
  501 {
  502         BOOL bValid= FALSE;
  503         if ( !CanSetSpeed( aIndex ) )
  504                 return FALSE; // Bewegungsgeschwindigkeit kann nicht gesetzt werden
  505 
  506         TMotorData *MtrData= &m_MotorList[aIndex];
  507         TMotor *Mtr= MtrData->m_lnkMotor;
  508         aSpeed= max( Mtr->GetMinSpeed(), min( fabs(aSpeed), Mtr->GetMaxSpeed() ) ); // Anpassung an Intervallgrenzen
  509         MtrData->m_Speed= aSpeed; // lokal setzen
  510         Mtr->SetSpeed( aSpeed );
  511         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_Speed", aSpeed, GetDigits(aIndex, bValid) );
  512         return bValid;
  513 };
  514 //----------------------------------------------------------------------------------------
  515 // Schrittweite
  516 
  517 BOOL TManJustage::SetAngleWidth ( const int aIndex, TAngle &aAngleWidth)
  518 {
  519         BOOL bValid= FALSE;
  520         if ( !CanSetAngleWidth( aIndex ) )
  521                 return FALSE; // Schrittweite kann nicht gesetzt werden
  522 
  523         TMotorData *MtrData= &m_MotorList[aIndex];
  524         TMotor *Mtr= MtrData->m_lnkMotor;
  525         Mtr->SetAngleWidth( aAngleWidth );  // im Motor setzen (hier auch Einpassung ins Intervall MinimalWith-MaximalWidth)
  526         aAngleWidth= Mtr->GetAngleWidth();  // korrigierten Wert lesen
  527         MtrData->m_AngleWidth= aAngleWidth; // lokal setzen
  528         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_AngleWidth", aAngleWidth, GetDigits(aIndex, bValid) + 1 );
  529         return bValid;
  530 };
  531 //----------------------------------------------------------------------------------------
  532 // OnTimer() hat auf Start/ Stop der Bewegung reagiert
  533 
  534 BOOL TManJustage::SetKzMoving ( const int aIndex, BOOL aIsMoving)
  535 {
  536         if ( !IsIndexValid ( aIndex ) )
  537                 return FALSE;
  538 
  539         m_MotorList[aIndex].m_KzMoving= aIsMoving;
  540         return TRUE;
  541 };
  542 //----------------------------------------------------------------------------------------
  543 // Offset bzw relative Null
  544 //----------------------------------------------------------------------------------------
  545 // setzen der relativen Null
  546 
  547 BOOL TManJustage::SetRelativeZero ( const int aIndex )
  548 {
  549         BOOL bValid= FALSE;
  550         if ( !CanSetOffset(aIndex) )
  551                 return FALSE; // darf nicht gesetzt werden
  552 
  553         TMotorData *MtrData= &m_MotorList[aIndex];
  554         TMotor *Mtr= MtrData->m_lnkMotor;
  555         ResetChannelOffset(aIndex); // hat Rückwirkungen auf SetRelativeZero, deshalb davor aufrufen
  556         if (!Mtr->SetRelativeZero())
  557                 return FALSE; // TRUE wenn erfolgreich, d.h bei Stillstand des Antriebs
  558 
  559         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_Offset", Mtr->GetAngleBias(), GetDigits(aIndex, bValid) );
  560         return bValid;
  561 };
  562 //----------------------------------------------------------------------------------------
  563 // aufheben der relativen Null
  564 
  565 BOOL TManJustage::ResetRelativeZero ( const int aIndex )
  566 {
  567         BOOL bValid= FALSE;
  568         if ( !CanResetRelativeZero(aIndex) )
  569                 return FALSE; // darf nicht gesetzt werden
  570 
  571         TMotorData *MtrData= &m_MotorList[aIndex];
  572         TMotor *Mtr= MtrData->m_lnkMotor;
  573         ResetChannelOffset(aIndex); // hat Rückwirkungen auf ResetRelativeZero, deshalb davor aufrufen
  574         if ( !Mtr->ResetRelativeZero() )
  575                 return FALSE; // TRUE wenn erfolgreich, d.h bei Stillstand des Antriebs
  576 
  577         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_Offset", 0, GetDigits(aIndex, bValid) );
  578         return bValid;
  579 };
  580 //----------------------------------------------------------------------------------------
  581 // lesen des aktuellen Offset für <Antrieb>
  582 
  583 TAngle TManJustage::GetOffset ( const int aIndex, BOOL &aValid ) const
  584 {
  585         aValid= FALSE;
  586         if ( !IsIndexValid ( aIndex ) )
  587                 return 0.0;
  588 
  589         aValid= TRUE;
  590         return m_MotorList[aIndex].m_lnkMotor->GetAngleBias();
  591 };
  592 //----------------------------------------------------------------------------------------
  593 // setzen des Offset für <Antrieb> direkt
  594 
  595 BOOL TManJustage::SetOffset ( const int aIndex, TAngle &aOffset )
  596 {
  597         BOOL bValid= FALSE;
  598         if ( !CanSetOffset( aIndex ) )
  599                 return FALSE; // darf nicht gesetzt werden
  600 
  601         TMotorData *MtrData= &m_MotorList[aIndex];
  602         TMotor *Mtr= MtrData->m_lnkMotor;
  603         ResetChannelOffset(aIndex); // hat Rückwirkungen auf SetAngleBias, deshalb davor aufrufen
  604         if (!Mtr->SetAngleBias( aOffset ))
  605                 return FALSE;  // an Intervallgrenzen anpassen und setzen
  606 
  607         IniWriteDouble( GetHWFile(), MtrData->m_MotorId, "MJ_Offset", aOffset, GetDigits(aIndex, bValid) );
  608         return bValid;
  609 };
  610 //----------------------------------------------------------------------------------------
  611 // Berechnungen zum Offset für <Antrieb>
  612 // Werte werden nicht in den Antrieb übernommen, dafür SetOffset... verwenden
  613 //----------------------------------------------------------------------------------------
  614 // Position in Offset umrechnen
  615 
  616 TAngle TManJustage::CalcOffsetFromAngle ( const int aIndex, TAngle &aAngle ) const
  617 {
  618         BOOL bValid= FALSE;
  619         if ( !IsIndexValid( aIndex ) )
  620                 return 0.0;
  621 
  622         TAngle Angle= m_MotorList[aIndex].m_lnkMotor->GetAngleAbs(FALSE, bValid); // absolute Position
  623         if (!bValid)
  624                 return 0.0;  // an Intervallgrenzen anpassen
  625 
  626         return aAngle - Angle; // neuer Offset ist: neue Position - absoluter Position
  627 };
  628 //----------------------------------------------------------------------------------------
  629 // Offset in Position umrechnen
  630 
  631 TAngle TManJustage::CalcAngleFromOffset ( const int aIndex, TAngle &aOffset ) const
  632 {
  633         BOOL bValid= FALSE;
  634         if ( !IsIndexValid( aIndex ) )
  635                 return 0.0;
  636 
  637         TMotorData *MtrData= &m_MotorList[aIndex];
  638         TMotor *Mtr= MtrData->m_lnkMotor;
  639         TAngle AngleAbs= Mtr->GetAngleAbs(FALSE, bValid); // absolute Position
  640         if (!bValid)
  641                 return 0.0;  // an Intervallgrenzen anpassen
  642 
  643         TAngle NewAngle= (aOffset + AngleAbs);
  644         SetInRange( NewAngle, Mtr->GetAngleMin(), Mtr->GetAngleMax() ); // Anpassung an Intervallgrenzen
  645         aOffset= NewAngle - AngleAbs;
  646         return NewAngle;  // neue Position ist: Offset + absoluter Antriebsposition
  647 };
  648 //----------------------------------------------------------------------------------------
  649 // ChannelOffset
  650 //----------------------------------------------------------------------------------------
  651 // Index DES PSD-Antriebs; ggf. -1
  652 
  653 int TManJustage::GetDetectorAxisIdx ( void ) const
  654 {
  655         if ( m_lnkDetector != 0 )
  656         {
  657                 EAxisType axis= m_lnkDetector->GetAxis();
  658                 if ( axis != (EAxisType)0 )
  659                         return GetMotorIdx(axis);
  660         }
  661         return -1;
  662 };
  663 //----------------------------------------------------------------------------------------
  664 // Nachkommastellen der Kanalbreite
  665 
  666 UINT TManJustage::GetDetectorDigits ( BOOL &aValid ) const
  667 {
  668         aValid= ( m_lnkDetector != 0 );
  669         if ( aValid ) return m_lnkDetector->GetAngleStepDigits();
  670 
  671         return 5;
  672 }
  673 //----------------------------------------------------------------------------------------
  674 // gibt die Bezeichnung des Detektors zurück; ggf. "PSD"
  675 
  676 LPCSTR TManJustage::GetDetectorName ( BOOL &aValid ) const
  677 {
  678         aValid= (m_lnkDetector != 0);
  679         if ( aValid ) return m_lnkDetector->GetCharacteristic();
  680 
  681         return "PSD";
  682 }
  683 //----------------------------------------------------------------------------------------
  684 // 1dim Detector und dessen Achse vorhanden ?
  685 
  686 BOOL TManJustage::HasDetectorAxis ( void ) const
  687 {
  688         return ( (m_lnkDetector != 0) && (GetDetectorAxisIdx() != -1) );
  689 };
  690 //----------------------------------------------------------------------------------------
  691 // lesen des aktuellen Kanals
  692 
  693 int TManJustage::GetChannel ( void ) const
  694 {
  695         if ( !HasDetectorAxis() )
  696                 return 0;
  697         return m_Channel;
  698 };
  699 //----------------------------------------------------------------------------------------
  700 // lesen des aktuellen Verhältnis: Winkel pro Kanal
  701 
  702 TAngle TManJustage::GetAnglePerChannel ( void ) const
  703 {
  704         if ( !HasDetectorAxis() )
  705                 return 0;
  706         return CalcValueInUnit(m_lnkDetector->GetUnit(), m_lnkDetector->GetWidth());
  707 };
  708 //----------------------------------------------------------------------------------------
  709 // setzen des aktuellen Kanals
  710 
  711 BOOL TManJustage::SetChannel ( int &aChannel )
  712 {
  713         BOOL bValid;
  714         if ( !HasDetectorAxis() )
  715         {
  716                 m_Channel= 0;
  717                 return FALSE;
  718         }
  719 
  720         int idx= GetDetectorAxisIdx();
  721         aChannel= max( m_lnkDetector->GetFirstChannel(), min( aChannel, m_lnkDetector->GetLastChannel() ) ); // Anpassung
  722         ResetChannelOffset(idx); // unbedingt vor GetOffset aufrufen, um das Antriebsoffset (ohne das aktuelle Kanaloffset!) auszulesen
  723         TAngle NewOffset= GetOffset(idx, bValid) + CalcChannelOffset(aChannel);
  724         if ( (!bValid) || (!SetOffset(idx, NewOffset)) ) // Offset konnte nicht gelesen oder gesetzt werden
  725                 return FALSE;
  726 
  727         m_Channel= aChannel; // erst nach SetOffset, weil m_Channel dort auf FirstChannel gesetzt wird (ResetChannelOffset)
  728         IniWriteLong( GetHWFile(), m_DetectorId, "MJ_Channel", m_Channel ); // KanalOffset
  729         return TRUE;
  730 };
  731 //----------------------------------------------------------------------------------------
  732 // Kanal-Offset Null setzen
  733 
  734 BOOL TManJustage::ResetChannelOffset( const int aIndex )
  735 {
  736         BOOL bValid= TRUE;
  737         if ( !HasDetectorAxis() )
  738                 return FALSE; // ist kein Detektor-Antrieb vorhanden
  739         if ( (aIndex == -1) || (aIndex != GetDetectorAxisIdx()) )
  740                 return FALSE; // der aktuelle ist nicht DER Detektor-Antrieb
  741     if ( m_Channel == m_lnkDetector->GetFirstChannel() )
  742                 return FALSE; // ist bereits zurückgesetzt (wichtig, sonst Endlosrekursion bei *1*
  743 
  744         TAngle NewOffset= GetOffset(aIndex, bValid) - CalcChannelOffset(m_Channel); // Anteil des derzeit gesetzen Kanaloffsets subtrahieren
  745         m_Channel= m_lnkDetector->GetFirstChannel(); // erst NACH CalcChannelOffset, aber VOR SetOffset setzen (sonst Endlosrekursion bei *1*)
  746         if ( bValid ) SetOffset(aIndex, NewOffset); // *1*
  747 
  748         IniWriteLong( GetHWFile(), m_DetectorId, "MJ_Channel", m_Channel ); // KanalOffset
  749         return TRUE;
  750 };
  751 //----------------------------------------------------------------------------------------
  752 // Berechnung des Kanal-Offset
  753 
  754 TAngle TManJustage::CalcChannelOffset ( TChannel &aChannel ) const
  755 {
  756         if ( !HasDetectorAxis() )
  757                 return 0.0;
  758         aChannel= max( m_lnkDetector->GetFirstChannel(), min( aChannel, m_lnkDetector->GetLastChannel() ) ); // Anpassung
  759         return ( -1 * (aChannel-m_lnkDetector->GetFirstChannel()) * CalcValueInUnit(m_lnkDetector->GetUnit(), m_lnkDetector->GetWidth()) );
  760 };
  761 //----------------------------------------------------------------------------------------
  762 // Berechnung der neuen Antriebsposition
  763 
  764 TAngle TManJustage::CalcChannelAngle ( TChannel &aChannel ) const
  765 {
  766         BOOL bValid= FALSE;
  767         if ( !HasDetectorAxis() )
  768                 return 0.0;
  769         int idx= GetDetectorAxisIdx();
  770         if ( idx == -1 )
  771                 return 0.0;
  772 
  773         TMotorData *MtrData= &m_MotorList[ idx ];
  774         TMotor *Mtr= MtrData->m_lnkMotor;
  775         TChannel ActChannel= m_Channel; // weil CalcChannelOffset eine Referenz erwartet (dies würde im Wiederspruch zur const-Methodendeklaration stehen)
  776         return ( Mtr->GetAngle( FALSE, bValid) - CalcChannelOffset(ActChannel) + CalcChannelOffset(aChannel) );
  777 };
  778 //----------------------------------------------------------------------------------------
  779 // Halbwertsbreitenmessung
  780 //----------------------------------------------------------------------------------------
  781 
  782 TDetector *TManJustage::GetDetector ( void ) const
  783 {
  784         return TDetectorManager::DetectorManager().GetDetector();
  785 };
  786 //----------------------------------------------------------------------------------------
  787 
  788 void TManJustage::UpdateDetector( void ) const
  789 {
  790         GetDetector()->UpdateViews(TRUE);
  791         Steering.DetectorRequest();
  792 };
  793 //----------------------------------------------------------------------------------------
  794 // starten der Messung
  795 
  796 BOOL TManJustage::DoStartMeasure ( const HWND aControlWnd )
  797 {
  798         if ( (!CanDoStartMeasure()) || (!aControlWnd) )
  799                 return FALSE;  // Halbwertsbreitenmessung kann nicht gestartet werden
  800 
  801         Steering.Reset();  // aktive Makroverarbeitung abbrechnen
  802         Steering.StartUp( aControlWnd, 0, GetDetector() );  // Fensterhandle zum Fenster, das die Bildschirmaktualisierung des Zählerfensters übernimmt; ausgewählten Detektor setzen; zweiter Paramater ("Beugung fein" wird vom Makro selbst ausgewählt) wird nicht benötigt
  803         Steering.Visualising( TRUE, FALSE );  //Fortschritt NUR in Statuszeile ausgeben
  804   if ( Steering.StartMacroExecution( Steering.GetMacroById(InquireHwb), 0 ) ) { // Makro starten; zweiter Parameter wird nicht benötigt
  805     m_IsMeasuring= TRUE;
  806     return TRUE;    
  807   } else return FALSE;
  808 };
  809 //----------------------------------------------------------------------------------------
  810 // stoppen der Messung
  811 
  812 BOOL TManJustage::DoStopMeasure ( void )
  813 {
  814   if ( !CanDoStopMeasure() ) return FALSE;
  815         return Steering.Reset(); //zum Stoppen der Makroverarbeitung; ToggleInterrupt zum Pausieren
  816 };
  817 //----------------------------------------------------------------------------------------
  818 // ==> TRUE <--> Messung aktiv
  819 
  820 BOOL TManJustage::IsMeasuring ( void ) const
  821 {
  822         return Steering.IsActive();
  823 };
  824 //----------------------------------------------------------------------------------------
  825 // ==> Messung abgebrochen?
  826 
  827 BOOL TManJustage::IsMeasureReset ( void ) const
  828 {
  829         return Steering.IsReset();
  830 };
  831 
  832 //----------------------------------------------------------------------------------------
  833 //OnTimer() will auf Start/ Stop der Makroverarbeitung reagieren
  834 
  835 BOOL TManJustage::GetKzMeasuring ( void ) const
  836 {
  837         return m_KzMeasuring;
  838 };
  839 //----------------------------------------------------------------------------------------
  840 // ==> TRUE <--> Messung aktiv
  841 
  842 BOOL TManJustage::GetMeasureProgress ( int &aCmdIdx, LPSTR aProgress, int &aCmdCount ) const
  843 {
  844         aCmdIdx= 0;
  845         aProgress[0]= 0;
  846         aCmdCount= 0;
  847         return Steering.GetProgress( aCmdIdx, aProgress, aCmdCount );
  848 };
  849 //----------------------------------------------------------------------------------------
  850 // ==> HWB
  851 
  852 double TManJustage::GetMeasureHwb ( void ) const
  853 {
  854         return Steering.GetHwb();
  855 };
  856 //----------------------------------------------------------------------------------------
  857 //OnTimer() hat auf Start/ Stop der Makroverarbeitung reagiert
  858 
  859 void TManJustage::SetKzMeasuring ( const BOOL aIsMeasuring )
  860 {
  861         m_KzMeasuring= aIsMeasuring;
  862 };
  863 //----------------------------------------------------------------------------------------
  864 // Zustand für Bewegung ermitteln
  865 //----------------------------------------------------------------------------------------
  866 // ist Direktbetrieb möglich
  867 
  868 BOOL TManJustage::CanDoDirect ( const int aIndex )
  869 {
  870         BOOL bValid= FALSE;
  871         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  872         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  873                 return FALSE; // inclusive IsIndexValid
  874 
  875         TMotorData *MtrData= &m_MotorList[aIndex];
  876         // TRUE <--> im Direktbetrieb
  877         return ( MtrData->m_MotionType == mtDirect );
  878 };
  879 //----------------------------------------------------------------------------------------
  880 // ist Fahrbetrieb möglich
  881 
  882 BOOL TManJustage::CanDoDrive ( const int aIndex, const EDirection aDirection )
  883 {
  884         BOOL bValid= FALSE;
  885         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  886         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  887                 return FALSE; // inclusive IsIndexValid
  888 
  889         TMotorData *MtrData= &m_MotorList[aIndex];
  890         // TRUE <-> im Fahrbetrieb
  891         if ( MtrData->m_MotionType != mtDrive )
  892                 return FALSE;
  893 
  894         TMotor *Mtr= MtrData->m_lnkMotor;
  895         TAngle Angle= Mtr->GetAngle(FALSE, bValid);
  896         // TRUE <--> im Fahrbetrieb
  897         if ( !bValid )
  898                 return FALSE;  // Auslesen der akt. Position ist fehlgeschlagen
  899 
  900         //Zielposition bereits erreicht?
  901         if ( aDirection == dUp )
  902                 return ( Angle < GetAngleMax(aIndex, bValid) );
  903         else
  904                 return ( GetAngleMin(aIndex, bValid) < Angle ); // aDirection==dDown
  905 };
  906 //----------------------------------------------------------------------------------------
  907 // ist Schrittbetrieb möglich
  908 
  909 BOOL TManJustage::CanDoStep ( const int aIndex, const EDirection aDirection )
  910 {
  911         BOOL bValid= FALSE;
  912         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  913         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  914                 return FALSE; // inclusive IsIndexValid
  915 
  916         TMotorData *MtrData= &m_MotorList[aIndex];
  917         // TRUE <--> im Schrittbetrieb
  918         if ( MtrData->m_MotionType != mtStep )
  919                 return FALSE;
  920 
  921         TMotor *Mtr= MtrData->m_lnkMotor;
  922         TAngle Angle= Mtr->GetAngle(FALSE, bValid);
  923         // TRUE <--> Auslesen der akt. Position erfolgreich
  924         if ( !bValid )
  925                 return FALSE;
  926 
  927         TAngle AngleWidth= GetAngleWidth(aIndex, bValid);
  928         //Ist die Zielposition des nächsten Schrittes im Intervall
  929         if ( aDirection == dUp )
  930                 return ( (Angle + AngleWidth) < GetAngleMax(aIndex, bValid) );
  931         else
  932                 return ( GetAngleMin(aIndex, bValid) < (Angle - AngleWidth) ); // aDirection==dDown
  933 };
  934 //----------------------------------------------------------------------------------------
  935 // ist Stoppen möglich
  936 
  937 BOOL TManJustage::CanDoStop ( const int aIndex )
  938 {
  939         BOOL bValid= FALSE;
  940 
  941         // TRUE <--> gültiger Antrieb, in Bewegung; Halbwertsbreitenmessung ist inaktiv
  942         return (IsMoving(aIndex, bValid)) && (bValid) && (!IsMeasuring() );
  943 };
  944 //----------------------------------------------------------------------------------------
  945 // Zustand zum Setzen von Parametern ermitteln
  946 //----------------------------------------------------------------------------------------
  947 // kann Betriebsart gesetzt werden
  948 
  949 BOOL TManJustage::CanSetMotionType ( const int aIndex )
  950 {
  951         BOOL bValid= FALSE;
  952 
  953         // TRUE <--> gültiger Antrien, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  954         return ( (!IsMoving( aIndex, bValid )) && (bValid) );
  955 };
  956 //----------------------------------------------------------------------------------------
  957 // kann Sollpostion gesetzt werden
  958 
  959 BOOL TManJustage::CanSetAngleDest ( const int aIndex )
  960 {
  961         BOOL bValid= FALSE;
  962         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  963         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  964                 return FALSE; // inclusive IsIndexValid
  965 
  966         TMotorData *MtrData= &m_MotorList[aIndex];
  967         // TRUE <--> im Direktbetrieb
  968         return ( MtrData->m_MotionType == mtDirect );
  969 };
  970 //----------------------------------------------------------------------------------------
  971 // kann Geschwindigkeit gesetzt werden
  972 
  973 BOOL TManJustage::CanSetSpeed ( const int aIndex )
  974 {
  975         BOOL bValid= FALSE;
  976         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  977         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  978                 return FALSE; // inclusive IsIndexValid
  979 
  980         TMotorData *MtrData= &m_MotorList[aIndex];
  981         // TRUE <--> im Direkt- ODER Fahrbetrieb
  982         return ( (MtrData->m_MotionType == mtDirect) || (MtrData->m_MotionType == mtDrive) );
  983 };
  984 //----------------------------------------------------------------------------------------
  985 // kann Schrittweite gesetzt werden
  986 
  987 BOOL TManJustage::CanSetAngleWidth ( const int aIndex )
  988 {
  989         BOOL bValid= FALSE;
  990         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
  991         if ( (IsMoving( aIndex, bValid)) || (!bValid) )
  992                 return FALSE; // inclusive IsIndexValid
  993 
  994         TMotorData *MtrData= &m_MotorList[aIndex];
  995         // TRUE <--> im Schrittbetrieb
  996         return ( MtrData->m_MotionType == mtStep );
  997 };
  998 
  999 //----------------------------------------------------------------------------------------
 1000 // setzen des Offset für <Antrieb> möglich ?
 1001 
 1002 BOOL TManJustage::CanSetOffset ( const int aIndex )
 1003 {
 1004         BOOL bValid= FALSE;
 1005 
 1006         // TRUE <-> gültiger Antrieb, nicht in Bewegung (d.h. auch Halbwertsbreitenmessung ist inaktiv)
 1007         return ( (!IsMoving(aIndex, bValid)) && (bValid) );
 1008 };
 1009 //----------------------------------------------------------------------------------------
 1010 // aufheben der Relativen Null
 1011 
 1012 BOOL TManJustage::CanResetRelativeZero ( const int aIndex )
 1013 {
 1014         BOOL bValid= FALSE;
 1015         // TRUE <--> gültiger Antrieb, nicht in Bewegung, Offset <> 0
 1016         return ( (CanSetOffset(aIndex)) && (HasOffset(aIndex, bValid)) && (bValid) );
 1017 };
 1018 //----------------------------------------------------------------------------------------
 1019 // kann Halbwertsbreitenmessung gestartet werden
 1020 
 1021 BOOL TManJustage::CanDoStartMeasure ( void )
 1022 {
 1023         BOOL bValid;
 1024         // TRUE <--> Halbwertsbreitenmessung ist inaktiv
 1025         if ( IsMeasuring() )
 1026                 return FALSE;
 1027 
 1028         // TRUE <--> Motor "Beugung Fein" bzw. "Omega" angeschlossenund Makro "Halbwertsbreite messen" sind vorhanden
 1029         if ( (GetMotorIdx(GetHwbAxis()) == -1) || (!Steering.GetMacroById( InquireHwb )) )
 1030                 return FALSE;
 1031 
 1032         // TRUE <--> alle Motoren im Stillstand
 1033         for (UINT i= 0; i < GetMotorCount(); i++ )
 1034                 if ( IsMoving( i, bValid ) )
 1035                         return FALSE;
 1036 
 1037         // wenn bis jetzt keine Einwände, dann kanns ja losgehen
 1038         return TRUE;
 1039 };
 1040 //----------------------------------------------------------------------------------------
 1041 // kann Halbwertsbreitenmessung gestoppt werden
 1042 
 1043 BOOL TManJustage::CanDoStopMeasure ( void ) const
 1044 {
 1045   return ( (IsMeasuring()) && (m_IsMeasuring) );
 1046 };
 1047 
 1048 //------------------------------------------------------------------------------
 1049 // Speeding
 1050 //------------------------------------------------------------------------------
 1051 // m_UpdateCount erhöhen 
 1052 UINT  TManJustage::BeginUpdate ( void ) {
 1053   m_UpdateCount++; // erst danach m_UpdateCount erhöhen; jetzt liefern GetAngle und IsMoving die zwischengespeicherten Werte
 1054   if ( m_UpdateCount==1 ) for (int i=0; i<GetMotorCount(); i++) { // Kennzeichnen, dass bislang keine Daten zwischengespeichert wurden
 1055     m_MotorList[i].m_SpAngle=  0;
 1056         m_MotorList[i].m_HasAngle= FALSE;
 1057     m_MotorList[i].m_SpMoving=  FALSE;
 1058         m_MotorList[i].m_HasMoving= FALSE;
 1059   }
 1060   return m_UpdateCount;
 1061 }
 1062 //----------------------------------------------------------------------------------------
 1063 // m_UpdateCount verringern
 1064 
 1065 UINT TManJustage::EndUpdate ( void ) {
 1066   if ( m_UpdateCount>0 ) m_UpdateCount--;
 1067   return m_UpdateCount;
 1068 }
 1069 
 1070 //------------------------------------------------------------------------------
 1071 // Auslesen der wirklichen Antriebsdaten ohne Speeding (Aquäivalent zu GetAngle und IsMoving)
 1072 //----------------------------------------------------------------------------------------
 1073 // aktuelle Antriebsposition beim Antrieb auslesen
 1074 TAngle TManJustage::DetermineAngle( const int aIndex, BOOL &aValid ) const
 1075 {
 1076         aValid= FALSE;
 1077         if ( !IsIndexValid ( aIndex ) )
 1078                 return 0.0;
 1079 
 1080         if (m_MotorList[aIndex].m_lnkMotor->IsMoveFinish())
 1081                 aValid= m_MotorList[aIndex].m_lnkMotor->GetAngle( 1 ); // mGetDistance
 1082         else
 1083                 aValid= m_MotorList[aIndex].m_lnkMotor->GetAngle( 0 ); // mGetDistanceProcess
 1084         return m_MotorList[aIndex].m_lnkMotor->GetAngle(); // aValid == TRUE <--> Position erfolgreich ausgelesen und umgerechnet
 1085 }
 1086 //----------------------------------------------------------------------------------------
 1087 // Antriebsstatus (in Bewegung?) beim Antrieb auslesen
 1088 
 1089 BOOL TManJustage::DetermineMoving ( const int aIndex, BOOL &aValid) const 
 1090 {
 1091         aValid= FALSE;
 1092         if ( !IsIndexValid ( aIndex ) )
 1093                 return FALSE;
 1094 
 1095         aValid= TRUE;
 1096 /*Geschwindigkeitsoptimierung: Bei neuen Physikrechnern bitte unbedingt wieder einkommentieren!!! (--> Steigerung der Robustheit); Zudem sind die Testfälle 
 1097   Test_MJN.1.hts, Test_MJN.2.hts, Test_MJN.3.hts, Test_MJN.4.hts, Test_MJN.5.hts und Test_MJN.6.hts anzupassen (siehe dort "##Geschw."-Kommentar).
 1098         // Beugung fein (DF) und Beugung grob (DC) dürfen nicht gleichzeitig bewegt werden können
 1099         int idx= -1;
 1100         if ( m_MotorList[aIndex].m_AxisType == DC )
 1101                 idx= GetMotorIdx(DF);
 1102         else if ( m_MotorList[aIndex].m_AxisType == DF )
 1103                 idx= GetMotorIdx(DC);
 1104         if ( (idx != -1) && (!m_MotorList[idx].m_lnkMotor->IsMoveFinish()) )
 1105                 return TRUE; // der Partnerantrieb bewegt sich, also bewegen wir uns auch (nicht IsMoving benutzen. sonst Endlosrekursion)
 1106 */
 1107         return ( (IsMeasuring()) || (!m_MotorList[aIndex].m_lnkMotor->IsMoveFinish()) ); // TRUE <--> Halbwertsbreite nicht gemessen wird und Antrieb im Stillstand  
 1108 }
 1109 
 1110 //----------------------------------------------------------------------------------------
 1111 // LastLine
 1112