Ignore:
Timestamp:
05/15/04 16:46:27 (21 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Cosy/main
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Cosy/main/MCaos.cc

    r2615 r4076  
    307307}
    308308
    309 void MCaos::Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t)
     309Ring MCaos::Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t)
    310310{
    311311    Leds &leds = *fLeds;
     
    344344
    345345    Rings rings;
    346     rings.CalcRings(leds, 266, 272);
     346    rings.CalcRings(leds, 266, 268);
    347347
    348348    const Ring &center = rings.GetCenter();
    349 
    350     f.DrawCircle(center, 0x80);
    351     f.DrawCircle(center,   5.0, 0x80);
    352     f.DrawCircle(center, 115.0, 0x80);
    353     f.DrawCircle(center, 190.0, 0x80);
    354     // f.MarkPoint(center.GetX(), center.GetY(), 0xa0);
    355349
    356350    // FIXME!
     
    380374    }
    381375
     376    return center;
    382377    /*
    383378        if (fCaosAnalyse->IsEntryEnabled(IDM_kStopAnalyse))
  • trunk/MagicSoft/Cosy/main/MCaos.h

    r2615 r4076  
    44#ifndef CAOS_Leds
    55#include "Leds.h"
     6#endif
     7#ifndef CAOS_Ring
     8#include "Ring.h"
    69#endif
    710
     
    6871    void ResetHistograms();
    6972
    70     void Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t);
     73    Ring Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t);
    7174};
    7275
  • trunk/MagicSoft/Cosy/main/MCosy.cc

    r3897 r4076  
    1 #include "MCosy.h"
    21#include "MCosy.h"
    32
     
    2221#include "MStarguider.h"
    2322#include "SlaStars.h"
     23#include "MPointing.h"
     24#include "MTracking.h"
    2425
    2526#include "slalib/slalib.h"  // FIXME: REMOVE
     
    3132
    3233typedef struct tm tm_t;
    33 
    34 /*
    35 #define GEAR_RATIO_ALT  2475.6 // [U_mot/U_tel(360deg)]
    36 #define GEAR_RATIO_AZ   5891.7 // [U_mot/U_tel(360deg)]
    37 
    38 #define RES_RE           500   // [re/U_mot]
    39 #define RES_SE         16384   // [se/U_tel(360deg)]
    40 */
    41 /*
    42  #define GEAR_RATIO_ALT (75.55*16384/1500) // 75.25 VERY IMPORTANT! unit=U_mot/U_tel
    43  #define GEAR_RATIO_AZ  (179.8*16384/1500)  // VERY IMPORTANT! unit=U_mot/U_tel
    44 */
    45 
    46 //const XY kGearRatio (GEAR_RATIO_ALT*RES_RE/RES_SE, GEAR_RATIO_AZ*RES_RE/RES_SE);   //[re/se]
    47 //const XY kGearRatio2(GEAR_RATIO_ALT*RES_RE/360.0,  GEAR_RATIO_AZ*RES_RE/360.0);    //[re/deg]
    4834
    4935/* +===================================+
     
    5440//#define EXPERT
    5541#undef EXPERT
    56 
    57 double MCosy::Rad2SE(double rad) const
    58 {
    59     return 16384.0/k2Pi*rad;
    60 }
    61 
    62 double MCosy::Rad2ZdRE(double rad) const
    63 {
    64     return 16384.0/k2Pi*rad*kGearRatio.X();
    65 }
    66 
    67 double MCosy::Rad2AzRE(double rad) const
    68 {
    69     return 16384.0/k2Pi*rad*kGearRatio.Y();
    70 }
    71 
    72 double MCosy::Deg2ZdRE(double rad) const
    73 {
    74     return rad*kGearRatio2.X();
    75 }
    76 
    77 double MCosy::Deg2AzRE(double rad) const
    78 {
    79     return rad*kGearRatio2.Y();
    80 }
    8142
    8243/*
     
    191152// --------------------------------------------------------------------------
    192153//
    193 // request the current positions from the rotary encoders.
    194 // use GetRePos to get the psotions. If the request fails the function
    195 // returns kFALSE, otherwise kTRUE
    196 //
    197 Bool_t MCosy::RequestRePos()
    198 {
    199     //
    200     // Send request
    201     //
    202     fMac2->RequestSDO(0x6004);
    203     fMac1->RequestSDO(0x6004);
    204 
    205     //
    206     // Wait until the objects are received.
    207     //
    208     fMac2->WaitForSdo(0x6004);
    209     fMac1->WaitForSdo(0x6004);
    210 
    211     //
    212     // If waiting was not interrupted everything is ok. return.
    213     //
    214     if (!(Break() || HasError() || HasZombie()))
    215         return kTRUE;
    216 
    217     //
    218     // If the waiting was interrupted due to a network error,
    219     // print some logging message.
    220     //
    221     if (HasError())
    222         lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
    223 
    224     return kFALSE;
    225 }
    226 
    227 // --------------------------------------------------------------------------
    228 //
    229154//  reads the Rotary encoder positions from the last request of the Macs.
    230155//
     
    253178// --------------------------------------------------------------------------
    254179//
    255 //  set the velocity and accelerations for position maneuvers.
    256 //
    257 //  The acceleratin is set as given (in percent of maximum).
    258 //  The velocity is given in percent, depending on the ratio (<1 or >1)
    259 //  one of the axis becomes a slower velocity. This is used for maneuvers
    260 //  in which both axis are moved synchromously and should reach their
    261 //  target position at the same time.
    262 //
    263 void MCosy::SetPosVelocity(const Float_t ratio, Float_t vel)
    264 {
    265     //
    266     // Set velocities
    267     //
    268     const int vr = fMac1->GetVelRes();
    269 
    270     vel *= vr;
    271 
    272     if (ratio <1)
    273     {
    274         fMac1->SetVelocity(vel);
    275         fMac2->SetVelocity(vel*ratio);
    276     }
    277     else
    278     {
    279         fMac1->SetVelocity(vel/ratio);
    280         fMac2->SetVelocity(vel);
    281     }
    282 }
    283 
    284 // --------------------------------------------------------------------------
    285 //
    286 // Does a relative positioning.
    287 //
    288 // The steps to move are given in a ZdAz object relative to the current
    289 // position. The coordinates are given in Roteryencoder steps.
    290 // Axis 1 is moved only if axe1==kTRUE, Axis 2 is moved only
    291 // if Axis 2==kTRUE. The function waits for the movement to be finished.
    292 //
    293 void MCosy::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
    294 {
    295     if (HasZombie())
    296         return;
    297 
    298     SetStatus(MDriveCom::kMoving);
    299 
    300     if (axe1) fMac2->StartRelPos(rd.Zd());
    301     if (axe2) fMac1->StartRelPos(rd.Az());
    302 #ifdef EXPERT
    303     cout << "Waiting for positioning..." << flush;
    304 #endif
    305     if (axe1) fMac2->WaitForSdo(0x6004, 1);
    306     if (axe2) fMac1->WaitForSdo(0x6004, 1);
    307 
    308     WaitForEndMovement();
    309 #ifdef EXPERT
    310     cout << "done." << endl;
    311 #endif
    312 }
    313 
    314 // --------------------------------------------------------------------------
    315 //
    316180// check for a break-signal (from the msgqueue) and errors.
    317181//
     
    341205        return;
    342206
    343     MTime t;
    344     t.Now();
     207    MTime t(-1);
    345208    lout << t << " - MCosy::WaitForEndMovement aborted...";
    346209    if (Break())
     
    434297}
    435298
    436 // --------------------------------------------------------------------------
    437 //
    438 // Move the telescope to the given position. The position must be given in
    439 // a ZdAz object in rad.
    440 //
    441 // The first positioning is done absolutely. If we didn't reach the
    442 // correct psotion we try to correct for this by 10 relative position
    443 // maneuvers. If this doesn't help positioning failed.
    444 //
    445 // As a reference the shaftencoder values are used.
    446 //
    447 int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
    448 {
    449     const ZdAz d = dst*kRad2Deg;
    450 
    451     MTime t;
    452     t.Now();
    453     lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
    454 
    455     //
    456     // Calculate new target position (shortest distance to go)
    457     //
    458     const ZdAz src = GetSePos(); // [se]
    459 
    460     //
    461     // Make sure that the motors are in sync mode (necessary if the
    462     // MACS has been rebooted from a Zombie state.
    463     //
    464     //InitSync();
    465     //if (fMac3->IsZombieNode())
    466     //    return false;
    467 
    468     //
    469     // Because we agreed on I don't search for the shortest move
    470     // anymore
    471     //
    472     // const ZdAz dest = CorrectTarget(src, dst);
    473     //
    474     ZdAz bend = fBending(dst); // [rad]
    475 
    476     const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
    477 
    478     if (!CheckRange(bend))
    479         return kFALSE;
    480 
    481     bend *= kRad2Deg;
    482     fZdAzSoll = dst;
    483 
    484     cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
    485     cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
    486     cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
    487     cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
    488 
    489     //
    490     // Set velocities
    491     //
    492     const int vr = fMac1->GetVelRes();
    493 
    494     int i;
    495     for (i=0; i<(track?1:10) && !(Break() || HasError() || HasZombie()); i++)
    496     {
    497 
    498         lout << "- Step #" << i << endl;
    499         //
    500         // Get Shaft Encoder Positions
    501         //
    502         const ZdAz p=GetSePos();
    503 
    504         //
    505         // calculate control deviation and rounded cd
    506         //
    507         ZdAz rd = dest-p; // [se]
    508 
    509         // ===========================================
    510         const ZdAz ist = dst-rd*TMath::Pi()/8192;
    511 
    512         const double p1 = ist.Zd()-19.0605/kRad2Deg;
    513         const double p2 = dst.Zd()-19.0605/kRad2Deg;
    514 
    515         const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
    516         const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
    517         // ===========================================
    518 
    519         ZdAz cd = rd;     // [se]
    520         cd.Round();
    521 
    522         //
    523         // Check if there is a control deviation on the axis
    524         //
    525         const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
    526         const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
    527 
    528         //
    529         // check if we reached the correct position already
    530         //
    531         if (!cdzd && !cdaz)
    532         {
    533             t.Now();
    534             lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
    535             SetStatus(MDriveCom::kStopped);
    536             return TRUE;
    537         }
    538 
    539         //
    540         // change units from se to re
    541         //
    542         rd *= kGearRatio; // [re]
    543         rd.Zd(f2-f1);
    544 
    545         //
    546         // Initialize Velocities so that we reach both positions
    547         // at the same time
    548         //
    549         if (i)
    550         {
    551             fMac1->SetAcceleration(0.1*vr);
    552             fMac2->SetAcceleration(0.1*vr);
    553 
    554             fMac1->SetDeceleration(0.1*vr);
    555             fMac2->SetDeceleration(0.1*vr);
    556 
    557             SetPosVelocity(1.0, 0.05);
    558         }
    559         else
    560         {
    561             if (rd.Az()>-15*kGearRatio.Y() && rd.Az()<15*kGearRatio.Y())
    562             {
    563 #ifdef EXPERT
    564                 cout << " -------------- LO ---------------- " << endl;
    565 #endif
    566                 fMac1->SetAcceleration(0.05*vr);
    567                 fMac1->SetDeceleration(0.05*vr);
    568             }
    569             else
    570             {
    571 #ifdef EXPERT
    572                 cout << " -------------- HI ---------------- " << endl;
    573                 fMac1->SetAcceleration(0.4*vr);// 0.4
    574                 fMac1->SetDeceleration(0.4*vr);// 0.4
    575 #else
    576                 fMac1->SetAcceleration(0.2*vr);
    577                 fMac1->SetDeceleration(0.1*vr);
    578 #endif
    579             }
    580 
    581 #ifdef EXPERT
    582             fMac2->SetAcceleration(0.4*vr);// 0.4
    583             fMac2->SetDeceleration(0.4*vr);// 0.4
    584             SetPosVelocity(fabs(rd.Ratio()), 0.2); // fast: 0.6, slow: 0.2
    585 #else
    586             fMac2->SetAcceleration(0.2*vr);
    587             fMac2->SetDeceleration(0.1*vr);
    588             SetPosVelocity(fabs(rd.Ratio()), 0.1);
    589 #endif
    590         }
    591 
    592         rd.Round();
    593 
    594         // FIXME? Check for Error or Zombie?
    595 
    596         /*
    597          cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
    598          cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
    599          cout << " +       dZd=" << setw(6) << cd.Zd() << "se  dAz=" << setw(6) << cd.Az() << "se" << endl;
    600          cout << " +       dZd=" << setw(6) << rd.Zd() << "re  dAz=" << setw(6) << rd.Az() << "re" << endl;
    601          cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
    602         */
    603 
    604         //
    605         // repositioning (relative)
    606         //
    607 
    608         lout << "- Do Relative Positioning..." << endl;
    609         DoRelPos(rd, cdzd, cdaz);
    610         lout << "- Relative Positioning Done" << endl;
    611     }
    612     if (i==1 && track && !(Break() || HasError() || HasZombie()))
    613     {
    614         t.Now();
    615         lout << t << " - Positioning done." << endl;
    616         SetStatus(MDriveCom::kStopped);
    617         return TRUE;
    618     }
    619 
    620     if (i<10)
    621         StopMovement();
    622     else
    623         SetStatus(MDriveCom::kStopped);
    624 
    625     t.Now();
    626     lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
    627     return FALSE;
    628 }
    629 
    630 // --------------------------------------------------------------------------
    631 //
    632 // Sets the tracking velocity
    633 //
    634 // The velocities are given in a ZdAz object in re/min. Return kTRUE
    635 // in case of success, kFALSE in case of failure.
    636 //
    637 Bool_t MCosy::SetVelocity(const ZdAz &v)
    638 {
    639     //
    640     // Send the new velocities for both axes.
    641     //
    642     fMac2->SendSDO(0x3006, 1, (LWORD_t)v.Zd());  // SetRpmVelocity [re/min]
    643     fMac1->SendSDO(0x3006, 1, (LWORD_t)v.Az());  // SetRpmVelocity [re/min]
    644 
    645     //
    646     // Wait for the objects to be acknoledged.
    647     //
    648     fMac2->WaitForSdo(0x3006, 1);
    649     fMac1->WaitForSdo(0x3006, 1);
    650 
    651     //
    652     // If the waiting for the objects wasn't interrupted return kTRUE
    653     //
    654     if (!(Break() || HasError() || HasZombie()))
    655         return kTRUE;
    656 
    657     //
    658     // print a message if the interruption was due to a Can-node Error
    659     //
    660     if (HasError())
    661         lout << "Error while setting velocity (SDO #3006)" << endl;
    662 
    663     return kFALSE;
    664 }
    665 
    666 // --------------------------------------------------------------------------
    667 //
    668 // Initializes Tracking mode
    669 //
    670 // Initializes the accelerations of both axes with 90% of the maximum
    671 // acceleration. Set the status for moving and tracking and starts thr
    672 // revolution mode.
    673 //
    674 bool MCosy::InitTracking()
    675 {
    676     // FIXME? Handling of Zombie OK?
    677     if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
    678         return false;
    679 
    680     //
    681     // Start revolution mode
    682     //
    683     fMac2->SetAcceleration(0.1*fMac2->GetVelRes());
    684     fMac2->SetDeceleration(0.1*fMac2->GetVelRes());
    685     if (fMac2->IsZombieNode())
    686         return false;
    687 
    688     fMac1->SetAcceleration(0.1*fMac1->GetVelRes());
    689     fMac1->SetDeceleration(0.1*fMac1->GetVelRes());
    690     if (fMac1->IsZombieNode())
    691         return false;
    692 
    693     SetStatus(MDriveCom::kMoving | MDriveCom::kTracking);
    694 
    695     fMac2->SetRpmMode(TRUE);
    696     if (fMac2->IsZombieNode())
    697         return false;
    698 
    699     fMac1->SetRpmMode(TRUE);
    700     if (fMac1->IsZombieNode())
    701         return false;
    702 
    703     return true;
    704 }
    705 
    706 // --------------------------------------------------------------------------
    707 //
    708 // Limits the speed.
    709 //
    710 // This function should work as a limiter. If a tracking error is too large
    711 // to be corrected fast enough we would get enormous velocities. These
    712 // velocities are limited to the maximum velocity.
    713 //
    714 Bool_t MCosy::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
    715 {
    716     Bool_t rc = kFALSE;
    717 
    718     //
    719     // How to limit the speed. If the wind comes and blowes
    720     // we cannot forbid changing of the sign. But on the other hand
    721     // we don't want fast changes!
    722     //
    723     ULong_t vrzd = fMac1->GetVelRes();
    724     ULong_t vraz = fMac2->GetVelRes();
    725 
    726 #define sgn(x) (x<0?-1:1)
    727 
    728     //
    729     // When speed changes sign, the maximum allowed speed
    730     // is 25% of the |v|
    731     //
    732     //const Float_t limit    = 0.25;
    733 
    734     //
    735     // The maximum allowed speed while tracking is 10%
    736     //
    737     const Float_t maxtrack = 0.1;
    738 /*
    739     if (sgn(vt->Az()) != sgn(vcalc.Az()))
    740         vt->Az(0);
    741 //    else
    742     {
    743         if (fabs(vt->Az()) < fabs(vcalc.Az()) *0.5)
    744             vt->Az(0.5*vcalc.Az());
    745 
    746         if (fabs(vt->Az()) > fabs(vcalc.Az()) *1.5)
    747             vt->Az(1.5*vcalc.Az());
    748     }
    749 
    750     if (sgn(vt->Zd()) != sgn(vcalc.Zd()))
    751         vt->Zd(0);
    752 //    else
    753     {
    754         if (fabs(vt->Zd()) > fabs(vcalc.Az()) *1.5)
    755             vt->Zd(1.5*vcalc.Zd());
    756 
    757         if (fabs(vt->Zd()) < fabs(vcalc.Az()) *0.5)
    758             vt->Zd(0.5*vcalc.Zd());
    759     }
    760     */
    761    /*
    762     if (sgn(vt->Az()) != sgn(vcalc.Az())
    763         && fabs(vt->Az()) < limit*fabs(vcalc.Az())
    764        )
    765         {
    766             lout << "Warning: Negative Azimuth speed limit (" << limit*100 << "%) exceeded... set to 0." << endl;
    767             vt->Az(0);
    768         }
    769     else*/
    770         if (fabs(vt->Az()) > maxtrack*vraz)
    771         {
    772             lout << "Warning: Azimuth speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Az()) << " > " << maxtrack*vraz << ")... limited." << endl;
    773             vt->Az(maxtrack*vraz*sgn(vcalc.Az()));
    774             rc=kTRUE;
    775         }
    776 /*
    777     if (sgn(vt->Zd()) != sgn(vcalc.Zd())
    778         && fabs(vt->Zd()) < limit*fabs(vcalc.Zd())
    779        )
    780         {
    781             lout << "Warning: Negative Altitude speed limit (" << limit*100 << "%) exceeded... set to 0." << endl;
    782             vt->Zd(0);
    783         }
    784     else
    785  */       if (fabs(vt->Zd()) > maxtrack*vrzd)
    786         {
    787             lout << "Warning: Altitude speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Zd()) <<" > " << maxtrack*vrzd << ")... limited." << endl;
    788             vt->Zd(maxtrack*vrzd*sgn(vcalc.Zd()));
    789             rc=kTRUE;
    790         }
    791     return rc;
    792 }
    793 /*
    794 Bool_t MCosy::AlignTrackingPos(ZdAz pointing, ZdAz &za) const
    795 {
    796     // pointing [deg]
    797     if (pointing.Zd()<0)
    798     {
    799         pointing.Zd(-pointing.Zd());
    800         pointing.Az(pointing.Az()+180);
    801     }
    802 
    803     const ZdAz se = GetSePos()*2*TMath::Pi()/16384;   // [rad]
    804     const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
    805 
    806     do
    807     {
    808         const Double_t d = unbendedse.Az() - pointing.Az();
    809         if (d>-180 && d<=180)
    810             break;
    811 
    812         pointing.Az(pointing.Az()+TMath::Sign(360., d));
    813     } while (1);
    814 
    815     const Bool_t rc = CheckRange(pointing);
    816     za = pointing/kRad2Deg; // [rad]
    817 
    818     if (!rc)
    819         lout << "Error: Aligned position out of Range." << endl;
    820 
    821     return rc;
    822 }
    823 */
    824 
    825299ZdAz MCosy::AlignTrackingPos(ZdAz pointing) const
    826300{
     
    837311    }
    838312
    839     const ZdAz se = GetSePos()*2*TMath::Pi()/16384;   // [rad]
     313    const ZdAz se = GetSePos()*TMath::TwoPi()/kResSE;   // [rad]
    840314    const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
    841315
     
    897371
    898372    dest -= point;
    899     dest *= 16384/TMath::Pi()/2; // [se]
    900     dest *= -kGearRatio;         // [re]
     373    dest *= -kGearTot/TMath::TwoPi(); // [re]
    901374
    902375    cout << "Using Starguider... dZd=" << dest.Zd() << " dAz=" << dest.Az() << endl;
     
    905378}
    906379
     380// --------------------------------------------------------------------------
     381//
     382// Move the telescope to the given position. The position must be given in
     383// a ZdAz object in rad.
     384//
     385// The first positioning is done absolutely. If we didn't reach the
     386// correct psotion we try to correct for this by 10 relative position
     387// maneuvers. If this doesn't help positioning failed.
     388//
     389// As a reference the shaftencoder values are used.
     390//
     391int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
     392{
     393    MPointing point(this, lout);
     394
     395//#ifdef EXPERT
     396//    point.SetAccDec(0.4, 0.4);
     397//    point.SetVelocity(0.2); // fast: 0.6, slow: 0.2
     398//#else
     399    point.SetPointAccDec(0.2, 0.1);
     400    point.SetPointVelocity(0.1);
     401//#endif
     402
     403    return point.SetPosition(dst, track);
     404}
     405
    907406void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
    908407{
    909     SlaStars sla(fObservatory);
    910 
    911     //
    912     // Position to actual position
    913     //
    914     sla.Now();
    915     ZdAz dest = sla.CalcZdAz(dst);
    916 
    917     lout << sla.GetTime() << ": Track Position " << dst.Ra()*kRad2Deg/15 << "h, " << dst.Dec()*kRad2Deg <<"deg" << endl;
    918 
    919     // FIXME: Determin tracking start point by star culmination
    920     if (dest.Az()<-TMath::Pi()/2)
    921     {
    922         lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
    923         dest.Az(dest.Az() + TMath::Pi()*2);
    924     }
    925 
    926     if (dest.Az()>3*TMath::Pi()/2)
    927     {
    928         lout << "Substracting 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
    929         dest.Az(dest.Az() -TMath::Pi()*2);
    930     }
    931 
    932     if (!SetPosition(dest, kTRUE))
    933     //if (!SetPosition(dest, kFALSE))
    934     {
    935         lout << "Error: Cannot start tracking, positioning failed." << endl;
    936         return;
    937     }
    938 
    939     //
    940     // calculate offset from present se position
    941     //
    942     const ZdAz sepos = GetSePos()*kGearRatio;
    943 
    944     if (!RequestRePos())
    945         return;
    946 
    947     //
    948     // Estimate Offset before starting to track
    949     //
    950     fOffset = sepos-GetRePos();
    951 
    952     /*
    953      cout << "Sepos:  " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
    954      cout << "Repos:  " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
    955      cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
    956      */
    957 
    958     //
    959     // Init accelerations and Rpm Mode
    960     //
    961     if (!InitTracking())
    962     {
    963         StopMovement();
    964         return;
    965     }
    966 
    967     XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
    968 
    969     sla.Now();
    970 //    lout << sla.GetTime() << " - Start tracking:";
    971 //    lout << " Ra: " << xy.X() << "h  " << "Dec: " << xy.Y() << "\xb0" << endl;
    972 
    973 /*#ifdef EXPERT
    974     ofstream fout("coordinates.txt");
    975     fout << xy;
    976     fout.close();
    977 #endif
    978 */    //
    979     // Initialize Tracker (slalib or starguider)
    980     //
    981     fRaDec = dst;
    982     fBackground = kBgdTracking;
    983 
    984     ZdAz pos = sla.CalcZdAz(fRaDec);
    985 
    986     lout << sla.GetTime() << " - Start Tracking: Ra=" <<xy.X() << "h Dec=";
    987     lout << xy.Y() << "\xb0 @ Zd=" << pos.Zd()*kRad2Deg <<"deg Az=" << pos.Az()*kRad2Deg <<"deg" << endl;
    988 
    989 //---    ofstream fout("log/cosy.pos");
    990 //---    fout << "Tracking:";
    991 //---    fout << " Ra: " << Rad2Deg(dst.Ra())  << "\x9c  ";
    992 //---    fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
    993 //---    fout << "     Mjd/10ms    V/re/min/4" << endl;
    994 
    995     //
    996     // We want to reach the theoretical position exactly in about 0.5s
    997     //
    998     // *OLD*const float dt = 1;  // 1 second
    999     const float dt = 5;//3;  // 2 second
    1000     while (!(Break() || HasError() || HasZombie()))
    1001     {
    1002         //
    1003         // Request Target position for this moment
    1004         //
    1005         sla.Now(dt);
    1006 
    1007         //
    1008         // Request theoretical Position for a time in the future (To+dt) from CPU
    1009         //
    1010          const ZdAz pointing = sla.CalcZdAz(fRaDec); // soll pointing [rad]
    1011 
    1012         //lout << sla.GetTime() << pointing.Zd()*kRad2Deg << " " << pointing.Az()*kRad2Deg << endl;
    1013         /*
    1014         ZdAz dest;
    1015         if (!AlignTrackingPos(pointing, dest))
    1016             break;
    1017             */
    1018         ZdAz dest = AlignTrackingPos(pointing);
    1019 
    1020         // lout << "DEST: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
    1021 
    1022         ZdAz vcalc = sla.GetApproxVel(fRaDec) * kGearRatio2*4./60.;
    1023         //lout << "Vcalc: " << dest.Zd() << " " << dest.Az() << endl;
    1024         vcalc *= kGearRatio2*4./60.; // [re/min]
    1025 
    1026         float dtime = -1;
    1027         if (kFALSE /*fUseStarguider*/)
    1028             dtime = Starguider(sla.GetMjd(), dest);
    1029 
    1030         if (dtime<0)
    1031         {
    1032             dest = fBending(dest);       // [rad]
    1033 
    1034             //lout << "DEST-BEND: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
    1035              
    1036             if (!CheckRange(dest))
    1037                 break;
    1038 
    1039             dest *= 16384/TMath::Pi()/2; // [se]
    1040             dest *= kGearRatio;          // [re]
    1041 
    1042             //
    1043             // Request absolute position of rotary encoder from Macs
    1044             //
    1045             if (!RequestRePos())
    1046                 break;
    1047 
    1048             //
    1049             // distance between (To+dt) and To [re]
    1050             // position time difference < 5usec
    1051             // fOffset does the synchronization between the
    1052             // Shaft- and the rotary encoders
    1053             dest -= GetRePos() + fOffset;
    1054 
    1055             dtime = dt;
    1056 
    1057             ZdAz repos = GetRePos();
    1058     //        lout << "Repos: " << repos.Zd()/kGearRatio.X() << " " << repos.Az()*kGearRatio.Y() << endl;
    1059    //         repos /= kGearRatio;
    1060             repos /= 16384/TMath::Pi()/2;
    1061             repos *= kRad2Deg;
    1062         }
    1063 
    1064         //
    1065         // Velocity to go [re/min] to reach the right position at time t+dt
    1066         // correct for the duration of RaDec2AltAz
    1067         //
    1068         const ZdAz v = dest*60.0/(dtime/*-(fMac2->GetTime()-sla)*/);
    1069 
    1070         //
    1071         // calculate real velocity of future [re/min]
    1072         // believing the Macs manual '/4' shouldn't be necessary, but it is.
    1073         //
    1074         ZdAz vt = v/4;
    1075         if (LimitSpeed(&vt, vcalc))
    1076         {
    1077             lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
    1078             lout << "vt: " << vt.Zd() << " " << vt.Az() << "re/min" << endl;
    1079             lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
    1080         }             
    1081         vt.Round();
    1082 
    1083         //
    1084         // check if the drive is fast enough to follow the star
    1085         //
    1086         if (vt.Zd()>.9*fMac1->GetVelRes() || vt.Az()>.9*fMac2->GetVelRes())
    1087         {
    1088             lout << "Error: Tracking speed faster than 90% of possible maximum velocity." << endl;
    1089             break;
    1090         }
    1091 
    1092         //
    1093         // Set theoretical velocity (as early after calculation as possible)
    1094         // Maybe we should attenuate the changes
    1095         //
    1096         if (!SetVelocity(vt))
    1097             break;
    1098 
    1099         //
    1100         // Now do 'unnecessary' things
    1101         //
    1102         fVelocity = vt/kGearRatio2*4;
    1103 
    1104 //---        const double mjd = fMac2->GetMjd();
    1105 //---        fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
    1106 //---        fout << setw(4) << vt.Zd() << " ";
    1107 //---        fout << setw(4) << vt.Az() << endl;
    1108         //
    1109         // FIXME? Calculate an accuracy for the tracking system?
    1110         // How good do we reach the calculated position in 'real'
    1111         // re valus?
    1112         //
    1113 
    1114 
    1115         //
    1116         // Update speed as often as possible.
    1117         // make sure, that dt is around 10 times larger than the
    1118         // update time
    1119         //
    1120         //
    1121         // The loop should not be executed faster than the ramp of
    1122         // a change in the velocity can be followed.
    1123         // (This is important on fast machines >500MHz)
    1124         //
    1125         /*
    1126         MTimeout t(1000);
    1127         while (!t.HasTimedOut())
    1128             usleep(1);
    1129          */
    1130         usleep(1000000); // 1s
    1131         cout << "." << flush;
    1132         //usleep(50000); // 0.05s
    1133     }
    1134 
    1135     sla.Now();
    1136 
    1137     fBackground = kBgdNone;
    1138     StopMovement();
    1139 
    1140     lout << sla.GetTime() << " - Tracking stopped." << endl;
     408    MTracking track(this, lout);
     409    track.SetOut(fOutRep);
     410//#ifdef EXPERT
     411//    track.SetPointAccDec(0.4, 0.4);
     412//    track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
     413//#else
     414    track.SetPointAccDec(0.2, 0.1);
     415    track.SetPointVelocity(0.1);
     416//#endif
     417    track.SetTrackAccDec(0.1, 0.1);
     418
     419    track.TrackPosition(dst);
    1141420}
    1142421
     
    1201480}
    1202481
    1203 void MCosy::StopTracking()
    1204 {
    1205     //
    1206     // Set status to Stopping
    1207     //
    1208     SetStatus(MDriveCom::kStopping);
    1209 
    1210     //
    1211     // set deceleration to 50%
    1212     //
    1213     cout << "Stopping tracking (dec=20%)..." << endl;
    1214     fMac1->SetDeceleration(0.2*fMac1->GetVelRes());
    1215     fMac2->SetDeceleration(0.2*fMac2->GetVelRes());
    1216 
    1217     fMac2->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
    1218     fMac1->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
    1219     fMac2->WaitForSdo(0x3006, 1);
    1220     fMac1->WaitForSdo(0x3006, 1);
    1221 
    1222     cout << "Waiting for end of movement..." << endl;
    1223     WaitForEndMovement();
    1224 
    1225     //
    1226     // Wait for the objects to be OKed.
    1227     //
    1228     fMac1->SetRpmMode(FALSE);
    1229     fMac2->SetRpmMode(FALSE);
    1230 
    1231     //
    1232     // Wait for the movement to really be finished.
    1233     //
    1234     //cout << "Waiting for end of movement..." << endl;
    1235     //WaitForEndMovement();
    1236 
    1237     //
    1238     // Check whether everything works fine.
    1239     //
    1240     CheckForError();
    1241     cout << "Movement stopped." << endl;
    1242 }
    1243 
    1244482bool MCosy::CheckNetwork()
    1245483{
     
    1281519
    1282520    case WM_STOP:
    1283         cout << "MCosy::Proc: Stop." << endl;
     521        //cout << "MCosy::Proc: Stop." << endl;
    1284522        if (!CheckNetwork())
    1285523            return (void*)0xebb0;
     
    1331569    case WM_TPOINT:
    1332570        {
    1333             cout << "WM_TPoint: start." << endl;
     571            //cout << "WM_TPoint: start." << endl;
    1334572            SlaStars sla(fObservatory);
    1335573            sla.Now();
     
    1340578            AltAz za=sla.CalcAltAz(rd*kDeg2Rad)*kRad2Deg;
    1341579
     580            if (!fOutTp)
     581            {
     582                //
     583                // open tpoint file
     584                //
     585                const TString name = GetFileName("tpoint/tpoint_%s.txt");
     586                cout << "TPoint-Cosy File ********* " << name << " ********** " << endl;
     587
     588                fOutTp = new ofstream(name);
     589                *fOutTp << "Magic Model  TPOINT data file" << endl;
     590                *fOutTp << ": ALTAZ" << endl;
     591                *fOutTp << "49 48 0 ";
     592                *fOutTp << sla.GetTime().Year() << " " << sla.GetTime().Month() << " " << sla.GetTime().Day() << " ";
     593                *fOutTp << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
     594                // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
     595            }
     596
    1342597            cout << "     Alt/Az: " << za.Alt() << "° " << za.Az() << "°" << endl;
    1343             *tpout << setprecision(7) << za.Az() << " " << za.Alt() << " ";
    1344 
    1345             ZdAz sepos = GetSePos()*TMath::Pi()*2/16384;;
     598            *fOutTp << setprecision(7) << za.Az() << " " << za.Alt() << " ";
     599
     600            ZdAz sepos = GetSePos()*TMath::TwoPi()/kResSE;
    1346601            za.Set(TMath::Pi()/2-sepos.Zd(), sepos.Az());
    1347602            za *= kRad2Deg;
    1348603
    1349604            cout << "     SE-Pos: " << za.Alt() << "° " << za.Az() << "°" << endl;
    1350             *tpout << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
     605            *fOutTp << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
    1351606
    1352607            if (fStarguider)
    1353608            {
    1354609                XY tp = fStarguider->GetCoordinates();
    1355                 *tpout << 90-tp.X() << " " << tp.Y() << " ";
     610                *fOutTp << 90-tp.X() << " " << tp.Y() << " ";
    1356611            }
    1357612
    1358             *tpout << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
    1359 
    1360             cout << "WM_TPoint: done. (return 0xaffe)" << endl;
     613            *fOutTp << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
     614
     615            //cout << "WM_TPoint: done. (return 0xaffe)" << endl;
    1361616        }
    1362617        return (void*)0xca1b;
    1363618
    1364619    case WM_TRACKPOS:
    1365         cout << "WM_TrackPosition: start." << endl;
     620        //cout << "WM_TrackPosition: start." << endl;
    1366621        {
    1367622            if (!CheckNetwork())
     
    1376631
    1377632            RaDec rd = sla.CalcRaDec(dest);
    1378             cout << dest.Zd()*180/3.1415 << " " << dest.Az()*180/3.1415 << endl;
    1379             cout << rd.Ra()*12/3.1415 << " " << rd.Dec()*180/3.1415 << endl;
    1380633            TrackPosition(rd);
    1381634        }
    1382         cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
     635        //cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
    1383636        return (void*)0xabcd;
    1384637
    1385638    case WM_POSITION:
    1386         cout << "WM_Position: start." << endl;
     639        //cout << "WM_Position: start." << endl;
    1387640        {
    1388641            if (!CheckNetwork())
     
    1392645            SetPosition(dest*kDeg2Rad);
    1393646        }
    1394         cout << "WM_Position: done. (return 0x7777)" << endl;
     647        //cout << "WM_Position: done. (return 0x7777)" << endl;
    1395648        return (void*)0x7777;
    1396649
    1397650    case WM_POSITION1:
    1398         cout << "WM_Position1: start." << endl;
     651        //cout << "WM_Position1: start." << endl;
    1399652        {
    1400653            if (!CheckNetwork())
     
    1404657            SetPosition(dest*kDeg2Rad, kTRUE);
    1405658        }
    1406         cout << "WM_Position: done. (return 0x7777)" << endl;
     659        //cout << "WM_Position: done. (return 0x7777)" << endl;
    1407660        return (void*)0x7777;
    1408661
    1409662    case WM_TESTSE:
    1410         cout << "WM_TestSe: start." << endl;
     663        //cout << "WM_TestSe: start." << endl;
    1411664        fBackground = mp ? kBgdSeTest : kBgdNone;
    1412         cout << "WM_TestSe: done. (return 0x1e51)" << endl;
     665        //cout << "WM_TestSe: done. (return 0x1e51)" << endl;
    1413666        return (void*)0x1e51;
    1414667
    1415668    case WM_GEAR:
    1416         cout << "WM_Gear: start." << endl;
     669        //cout << "WM_Gear: start." << endl;
    1417670        fBackground = mp ? kBgdGear : kBgdNone;
    1418         cout << "WM_Gear: done. (return 0xfeaf)" << endl;
     671        //cout << "WM_Gear: done. (return 0xfeaf)" << endl;
    1419672        return (void*)0xfeaf;
    1420673
    1421674    case WM_DISPLAY:
    1422         cout << "WM_Display: start." << endl;
     675        //cout << "WM_Display: start." << endl;
    1423676        fTriggerDisplay = kTRUE;
    1424         cout << "WM_Disply: done. (return 0xd1e1)" << endl;
     677        //cout << "WM_Disply: done. (return 0xd1e1)" << endl;
    1425678        return (void*)0xd1e1;
    1426679
    1427680    case WM_TRACK:
    1428         cout << "WM_Track: START" << endl;
     681        //cout << "WM_Track: START" << endl;
    1429682        {
    1430683            RaDec dest = ((RaDec*)mp)[0];
     
    1435688            TrackPosition(dest*kDeg2Rad);
    1436689        }
    1437         cout << "WM_Track: done. (return 0x8888)" << endl;
     690        //cout << "WM_Track: done. (return 0x8888)" << endl;
    1438691        return (void*)0x8888;
    1439692
    1440693    case WM_NEWTRACK:
    1441         cout << "WM_NewTrack: START" << endl;
     694        //cout << "WM_NewTrack: START" << endl;
    1442695        fRaDec = *((RaDec*)mp);
    1443         cout << "WM_NewTrack: done. (return 0x9999)" << endl;
     696        //cout << "WM_NewTrack: done. (return 0x9999)" << endl;
    1444697        return (void*)0x9999;
    1445698
    1446699    case WM_LOADBENDING:
    1447         cout << "WM_LoadBending: START" << endl;
     700        //cout << "WM_LoadBending: START" << endl;
    1448701        fBending.Load("bending.txt");
    1449         cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
     702        //cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
    1450703        return (void*)0xbe0d;
    1451704
    1452705    case WM_RESETBENDING:
    1453         cout << "WM_ResetBending: START" << endl;
     706        //cout << "WM_ResetBending: START" << endl;
    1454707        fBending.Reset();
    1455         cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
     708        //cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
    1456709        return (void*)0xbe0e;
    1457710
    1458711    case WM_HOME:
    1459         cout << "WM_Home: START" << endl;
     712        //cout << "WM_Home: START" << endl;
    1460713        if (!CheckNetwork())
    1461714            return (void*)0xebb0;
     
    1485738            */
    1486739        }
    1487         cout << "WM_Home: done. (return 0x403e)" << endl;
     740        //cout << "WM_Home: done. (return 0x403e)" << endl;
    1488741        return (void*)0x403e;
    1489742
     
    1510763            a1 *= kRad2Deg;
    1511764
    1512             const ZdAz a2 = a1*16384/360;
     765            const ZdAz a2 = a1*kResSE/360;
    1513766
    1514767            cout << "Zd/Az bended:  " << a1.Zd() << "° " << a1.Az() << "°" << endl;
     
    1519772    case WM_ENDSWITCH:
    1520773        {
    1521             ZdAz pos = GetSePos()*TMath::Pi()*2/16384;
     774            ZdAz pos = GetSePos()*TMath::TwoPi()/kResSE;
    1522775            pos = fBending.SubtractOffsets(pos)*kRad2Deg;
    1523776
     
    1575828
    1576829    cout << "Reading gear ratios..." << flush;
    1577     const Double_t gaz = env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0);
    1578     const Double_t gzd = env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0);
    1579 
    1580     Double_t resreaz = 0;
     830    kGear.Y(env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0));
     831    kGear.X(env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0));
     832
     833    kResRE.Y(0);
    1581834    if (fMac1 && !fMac1->IsZombieNode())
    1582         resreaz = fMac1->GetRes();
     835        kResRE.Y(fMac1->GetRes());
    1583836    else
    1584837        if (fMac3 && !fMac3->IsZombieNode())
    1585             resreaz = fMac3->GetRes();
     838            kResRE.Y(fMac3->GetRes());
    1586839        else
    1587             resreaz = env.GetValue("Az_ResRE[re/U_mot]", 1500);
    1588 
    1589     Double_t resrezd = 0;
     840            kResRE.Y(env.GetValue("Az_ResRE[re/U_mot]", 1500));
     841
     842    kResRE.X(0);
    1590843    if (fMac2 && !fMac2->IsZombieNode())
    1591         resrezd = fMac2->GetRes();
     844        kResRE.X(fMac2->GetRes());
    1592845    else
    1593         resrezd = env.GetValue("Zd_ResRE[re/U_mot]", 1500);
    1594 
    1595     Double_t ressezd = 0;
     846        kResRE.X(env.GetValue("Zd_ResRE[re/U_mot]", 1500));
     847
     848    kResSE.X(0);
    1596849    if (fZd1 && !fZd1->IsZombieNode())
    1597         ressezd = fZd1->GetPhysRes();
     850        kResSE.X(fZd1->GetPhysRes());
    1598851    else
    1599852        if (fZd2 && !fZd2->IsZombieNode())
    1600             ressezd = fZd2->GetPhysRes();
     853            kResSE.X(fZd2->GetPhysRes());
    1601854        else
    1602             ressezd = env.GetValue("Zd_ResSE[se/U_mot]", 16384);
    1603 
    1604     Double_t resseaz = 0;
     855            kResSE.X(env.GetValue("Zd_ResSE[se/U_mot]", 16384));
     856
     857    kResSE.Y(0);
    1605858    if (fAz && !fAz->IsZombieNode())
    1606         resseaz = fAz->GetPhysRes();
     859        kResSE.Y(fAz->GetPhysRes());
    1607860    else
    1608         resseaz = env.GetValue("Az_ResSE[se/U_mot]", 16384);
    1609 
    1610     kGearRatio.Set (gzd*resrezd*4/ressezd, gaz*resreaz*4/resseaz);  //[re/se]
    1611     kGearRatio2.Set(gzd*resrezd*4/360.0,   gaz*resreaz*4/360.0);    //[re/deg]
     861        kResSE.Y(env.GetValue("Az_ResSE[se/U_mot]", 16384));
     862
     863    // believing the Macs manual '*4' shouldn't be necessary, but it is.
     864    // Because the a RE is 4 quad counts.
     865    // Calculating speeds we have to convert back to qc
     866    kResRE  *= 4;
     867    kGearTot = kResRE*kGear;
     868
    1612869    cout << "done." << endl;
    1613870
    1614871    cout << " * Setting Gear Ratios:" << endl;
    1615872    cout << "   --------------------" << endl;
    1616     cout << " *  X: " << gzd << "*" << resrezd << "/" << ressezd << "=4*" << kGearRatio.X() << endl;
    1617     cout << " *  Y: " << gaz << "*" << resreaz << "/" << resseaz << "=4*" << kGearRatio.Y() << endl;
     873    cout << " *  X: " << kGear.X() << "*" << kResRE.X()/4 << "/" << kResSE.X() << "=4*" << kGearTot.X() << "/" << kResSE.X() << endl;
     874    cout << " *  Y: " << kGear.Y() << "*" << kResRE.Y()/4 << "/" << kResSE.Y() << "=4*" << kGearTot.Y() << "/" << kResSE.Y() << endl;
    1618875}
    1619876
     
    1632889    fMac3->SetDeceleration(0.2*res);
    1633890    fMac3->StartPosSync();
    1634 }
    1635 
    1636 void MCosy::TalkThreadTracking()
    1637 {
    1638     if (fZd1->IsZombieNode() && fZd2->IsZombieNode())
    1639         return;
    1640 
    1641     if (fAz->IsZombieNode())
    1642         return;
    1643 
    1644     if (!fMac1 || !fMac2)
    1645         return;
    1646 
    1647     lout << "- Tracking Thread started..." << endl;
    1648 
    1649     SlaStars sla(fObservatory);
    1650     sla.Now();
    1651 
    1652     ZdAz old;
    1653     ZdAz ist = GetSePos();              // [se]
    1654 
    1655     ZdAz time;
    1656 
    1657     ZdAz sollzd = sla.CalcZdAz(fRaDec); // [rad]
    1658     ZdAz sollaz = sollzd;               // [rad]
    1659 
    1660     //
    1661     // only update fTrackingError while tracking
    1662     //
    1663     bool phca1=false;
    1664     bool phca2=false;
    1665     bool phcaz=false;
    1666 
    1667     while (fBackground==kBgdTracking)
    1668     {
    1669         //
    1670         // Make changes (eg wind) smoother - attenuation of control function
    1671         //
    1672         const float weight = 1.; //0.3;
    1673 
    1674         //
    1675         // This is the time constant which defines how fast
    1676         // you correct for external influences (like wind)
    1677         //
    1678         fZd1->ResetPosHasChanged();
    1679         fZd2->ResetPosHasChanged();
    1680         fAz->ResetPosHasChanged();
    1681         do
    1682         {
    1683             phca1 = fZd1->PosHasChanged();
    1684             phca2 = fZd2->PosHasChanged();
    1685             phcaz = fAz->PosHasChanged();
    1686             usleep(1);
    1687         } while (!phca1 && !phca2 && !phcaz && fBackground==kBgdTracking);
    1688 
    1689         //---usleep(100000); // 0.1s
    1690 
    1691         //
    1692         // get position, where we are
    1693         //
    1694         old = ist;
    1695         ist = GetSePos(); // [se]
    1696 
    1697         //
    1698         // if the position didn't change continue
    1699         //
    1700         /*---
    1701          if ((int)ist.Zd() == (int)old.Zd() &&
    1702          (int)ist.Az() == (int)old.Az())
    1703          continue;
    1704          */
    1705         ZdAz istre = GetRePosPdo();
    1706 
    1707         //
    1708         // Get time from last shaftencoder position change (position: ist)
    1709         // FIXME: I cannot take the avarage
    1710         //
    1711         // FIXME
    1712         //time.Zd(fZd1->GetMjd());
    1713         /* OLD* */
    1714         if (fZd1->GetMjd()>fZd2->GetMjd())
    1715             time.Zd(fZd1->GetMjd());
    1716         else
    1717             time.Zd(fZd2->GetMjd());
    1718 
    1719         //time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
    1720         time.Az(fAz->GetMjd());
    1721 
    1722         //
    1723         // if Shaftencoder changed position
    1724         // calculate were we should be
    1725         //
    1726         if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
    1727         {
    1728             sollzd = sla.CalcZdAz(fRaDec, time.Zd()); // [rad]
    1729             /*
    1730             ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
    1731             sollzd = CorrectTarget(ist, dummy); // [se]
    1732             */
    1733             fOffset.Zd(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight);
    1734         }
    1735 
    1736         if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
    1737         {
    1738             sollaz = sla.CalcZdAz(fRaDec, time.Az()); // [rad]
    1739             /*
    1740             ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
    1741             sollaz = CorrectTarget(ist, dummy); // [se]
    1742             */
    1743             fOffset.Az(fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
    1744         }
    1745 
    1746         ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad]
    1747 
    1748         fZdAzSoll = AlignTrackingPos(soll);
    1749 
    1750         ist *= TMath::Pi()*2/16384;
    1751         soll = fBending(fZdAzSoll);
    1752         fTrackingError.Set(ist.Zd()-soll.Zd(), ist.Az()-soll.Az());
    1753 
    1754         //---            fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
    1755         //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Zd() << "  ";
    1756         //---            fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
    1757         //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Az() << endl;
    1758     }
    1759 
    1760     lout << "- Tracking Thread done." << endl;
    1761 
    1762     //---        fout << endl << endl;
    1763891}
    1764892
     
    1813941        }
    1814942
    1815         Double_t apos = (pos[0]-pos[1])/2 * TMath::Pi()*2 / 16384;
     943        Double_t apos = (pos[0]-pos[1])/2 * TMath::TwoPi() / kResSE.X();
    1816944
    1817945        ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;
     
    1865993        ZdAz dre = re-re0;
    1866994
    1867         if (fabs(dse.Zd())*144>16384) // Each 2.5deg (144)
     995        if (fabs(dse.Zd())*144>kResSE.X()) // Each 2.5deg (144)
    1868996        {
    1869997            se0.Zd(se.Zd());
     
    18721000            se -= dse/2;
    18731001
    1874             ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
     1002            ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
    18751003            ((TH3*)fHist)->Fill(bend.Zd(), bend.Az(), dre.Zd()/dse.Zd());
    18761004        }
    18771005
    1878         if (fabs(dse.Az())*144>16384) // Each 2.5deg (144)
     1006        if (fabs(dse.Az())*144>kResSE.Y()) // Each 2.5deg (144)
    18791007        {
    18801008            se0.Az(se.Az());
     
    18831011            se -= dse/2;
    18841012
    1885             ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
     1013            ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
    18861014            ((TH3*)fHist)->Fill(bend.Az(), bend.Az(), dre.Az()/dse.Az());
    18871015        }
     
    19271055        case kBgdNone:
    19281056            continue;
    1929 
     1057/*#ifndef NEWALGO
    19301058        case kBgdTracking:
    19311059            TalkThreadTracking();
    19321060            continue;
    1933 
     1061#endif*/
    19341062        case kBgdSeTest:
    19351063            TalkThreadSeTest();
     
    19521080
    19531081    // GetPointingPos [deg]
    1954     const ZdAz seist = GetSePos()*2*TMath::Pi()/16384; // [se]
    1955 
    1956     //cout << seist.Zd()*kRad2Deg << " " << seist.Az()*kRad2Deg << endl;
    1957 
    1958     ZdAz back = fBending.CorrectBack(seist)*180/TMath::Pi();
    1959 
    1960     //cout << back.Zd() << " " << back.Az() << endl;
    1961 
    1962     return back;
     1082    const ZdAz seist = GetSePos()*TMath::TwoPi()/kResSE; // [rad]
     1083    return fBending.CorrectBack(seist)*TMath::RadToDeg();
    19631084}
    19641085
    19651086Bool_t MCosy::HandleTimer(TTimer *t)
    19661087{
     1088    const Int_t rc = fMutexGui.TryLock();
     1089    if (rc==13)
     1090        cout << "MCosy::HandleTimer - mutex is already locked by this thread" << endl;
     1091
     1092    if (rc)
     1093    {
     1094        lout << "* GUI update skipped due to locked mutex." << endl;
     1095        return kTRUE;
     1096    }
     1097
    19671098    //
    19681099    // Update Gui, foremer MTGui.
     
    19751106        fAz->DisplayVal();
    19761107
    1977     ZdAz bendist = GetPointingPos();
    1978 
    19791108    Byte_t avail = 0;
    19801109
     
    19891118        SetStatus(MDriveCom::kError);
    19901119
    1991     lout.UpdateGui();
    1992 
     1120    ZdAz bendist = GetPointingPos();
     1121    fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
     1122
     1123    fWin->UpdateWeather(*fCom);
    19931124    fWin->Update(bendist, fTrackingError, fVelocity, /*fOffset,*/
    19941125                 fRaDec, fZdAzSoll, fStatus, avail);
    19951126
     1127    lout.UpdateGui();
     1128
    19961129    const Bool_t trigger = fTriggerDisplay;
    19971130    fTriggerDisplay = kFALSE;
     
    20031136        DisplayHistGear(!trigger);
    20041137
    2005     // FIXME: Not thread safe!
    2006     static int i=0;
    2007     if (i++==7)
    2008     {
    2009         fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
    2010         i=0;
    2011     }
     1138    if (fMutexGui.UnLock()==13)
     1139        cout << "MCosy::HandleTimer - tried to unlock mutex locked by other thread." << endl;
     1140
    20121141    return kTRUE;
    20131142}
     
    21951324    fAz =new ShaftEncoder(id6, "SE/Az",  lout);
    21961325
     1326    fZd1->SetReport(fOutRep);
     1327    fZd2->SetReport(fOutRep);
     1328    fAz->SetReport(fOutRep);
     1329
    21971330    lout << "- Connecting devices to network." << endl;
    21981331
     
    22651398}
    22661399*/
     1400
     1401TString MCosy::GetFileName(const char *fmt)
     1402{
     1403    // FIXME: Timeout missing
     1404    while (1)
     1405    {
     1406        MTime time(-1);
     1407        const TString name = Form(fmt, (const char*)time.GetFileName());
     1408        if (gSystem->AccessPathName(name, kFileExists))
     1409            return name;
     1410            break;
     1411
     1412        usleep(1000);
     1413    }
     1414    return "";
     1415}
     1416
    22671417MCosy::MCosy(/*int mode,*/ const char *dev, const int baud, MLog &out)
    2268 : Network(dev, baud, out), fObservatory(MObservatory::kMagic1), fStarguider(NULL), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fBackground(kBgdNone), fStatus(MDriveCom::kStopped)
     1418: Network(dev, baud, out), fObservatory(MObservatory::kMagic1), fStarguider(NULL), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fBackground(kBgdNone), fStatus(MDriveCom::kStopped), fOutTp(0), fOutRep(0)
    22691419{
    22701420    TEnv env(".cosyrc");
     
    22751425    const Int_t id5 = env.GetValue("Zd_Id-SE2",  5); //5
    22761426    const Int_t id6 = env.GetValue("Az_Id-SE",   6); //6
     1427
     1428    TString name = GetFileName("rep/cosy_%s.rep");
     1429    cout << "Open Repfile: " << name << endl;
     1430    fOutRep = new MLog(name, kTRUE);
     1431
    22771432/*
    22781433    lout << "- Program in ";
     
    23001455    fAz->SetDisplay(fWin->GetLabel1());
    23011456
    2302     //
    2303     // open tpoint file
    2304     //
    2305     MTime time;
    2306     TString name;
    2307     while (1)
    2308     {
    2309         time.Now();
    2310         name = Form("tpoint/tpoint_%s.txt", (const char*)time.GetFileName());
    2311         if (gSystem->AccessPathName(name, kFileExists))
    2312             break;
    2313     }
    2314 
    2315     cout << "TPoint File ********* " << name << " ********** " << endl;
    2316 
    2317     tpout = new ofstream(name);
    2318     *tpout << "Magic Model  TPOINT data file" << endl;
    2319     *tpout << ": ALTAZ" << endl;
    2320     *tpout << "49 48 0 ";
    2321     *tpout << time.Year() << " " << time.Month() << " " << time.Day() << " ";
    2322     *tpout << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
    2323     // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
    2324 
    2325     fCom = new MDriveCom(this, out);
     1457    fCom = new MDriveCom(this, *fOutRep);
    23261458    fCom->Start();
    23271459}
     
    23491481MCosy::~MCosy()
    23501482{
    2351     *tpout << "END" << endl;
    2352     //streampos size = tpout.tellp();
    2353     delete tpout;
     1483    if (fOutTp)
     1484    {
     1485        *fOutTp << "END" << endl;
     1486        delete fOutTp;
     1487    }
     1488    delete fOutRep;
    23541489
    23551490    cout << "Deleting GUI timer." << endl;
     
    23591494
    23601495    cout << "Deleting Nodes." << endl;
     1496
     1497    fZd1->SetReport(0);
     1498    fZd2->SetReport(0);
     1499    fAz->SetReport(0);
    23611500
    23621501    delete fAz;
  • trunk/MagicSoft/Cosy/main/MCosy.h

    r3897 r4076  
    88#include "MBending.h"
    99
    10 #ifndef MARS_Mobservatory
     10#ifndef MARS_MObservatory
    1111#include "MObservatory.h"
     12#endif
     13#ifndef ROOT_TMutex
     14#include <TMutex.h>
    1215#endif
    1316
     
    6265{
    6366    friend class MTTalk;
     67    friend class MPointing;
     68    friend class MTracking;
    6469
    6570private:
     
    8388                          // with a generic interface to both...
    8489
     90    TMutex fMutexGui;
     91
    8592    enum BackgroundAction_t
    8693    {
    8794        kBgdNone,
    88         kBgdTracking,
     95        //kBgdTracking,
    8996        kBgdSeTest,
    9097        kBgdSeTestDispl,
     
    96103
    97104    ZdAz  fTrackingError; // [rad] Tracking Offset between SE and calc-pos
    98     ZdAz  fOffset;        // Offset between se and re coordinate system [re]
    99105    ZdAz  fZdAzSoll;      // [rad] Soll position when moving
    100106    RaDec fRaDec;         // Position to track
     
    107113    Bool_t fTriggerDisplay;
    108114
    109     XY kGearRatio;        // describing the gear of the system [re/se]
    110     XY kGearRatio2;       // describing the gear of the system [re/deg]
     115    XY kResSE;   // describing the resolution of the system [se/U_tel]
     116    XY kResRE;   // describing the resolution of the system [re/U_mot]
     117    XY kGear;    // describing the resolution of the system [U_mot/U_tel]
     118    XY kGearTot; // describing the resolution of the system [re/U_tel]
    111119
    112120    MBending fBending;
     
    114122    UInt_t fStatus;
    115123
    116     ofstream *tpout;
    117 
    118     //Bool_t AlignTrackingPos(ZdAz pointing, ZdAz &za) const;
     124    ofstream *fOutTp;
     125    MLog     *fOutRep;
     126
    119127    ZdAz AlignTrackingPos(ZdAz pointing) const;
    120128    Bool_t CheckRange(const ZdAz &d) const;
    121129    Double_t Starguider(Double_t mjd, ZdAz &dest) const;
    122130
    123     double Rad2SE(double rad) const;
    124     double Rad2ZdRE(double rad) const;
    125     double Rad2AzRE(double rad) const;
    126     double Deg2ZdRE(double rad) const;
    127     double Deg2AzRE(double rad) const;
    128 
    129131    void SetStatus(UInt_t stat) { fStatus = stat; }
    130132    UInt_t GetStatus() const { return fStatus; }
     
    133135    ZdAz GetRePosPdo();
    134136    ZdAz GetSePos() const; // [se]
    135 
    136     Bool_t RequestRePos();
    137     Bool_t SetVelocity(const ZdAz &v);
    138 
    139     void SetPosVelocity(const Float_t ratio, Float_t vel);
    140 
    141     void DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2);
     137    // FIXME: Must depend on the Shaftencoder mounted
     138    ZdAz GetSePosRad() const { return GetSePos()*TMath::TwoPi()/16384; } // [rad]
    142139
    143140    void InitSync();
    144     bool InitTracking();
    145     Bool_t LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const;
    146141
    147142    void TalkThread();
    148     void TalkThreadTracking();
    149143    void TalkThreadSeTest();
    150144    void TalkThreadGear();
     
    154148
    155149    int  SetPosition(const ZdAz &dst, Bool_t track=kFALSE);
     150    void TrackPosition(const RaDec &dst); // ra, dec [rad]
    156151
    157152    void TerminateApp();
    158 
    159     void TrackPosition(const RaDec &dst); // ra, dec [rad]
    160153
    161154    int StopWaitingForSDO() const;
     
    163156
    164157    void StopMovement();
    165     void StopTracking();
    166158
    167159    void WaitForEndMovement();
     
    188180    ZdAz GetPointingPos(void) const;
    189181    void SetStarguider(MStarguider *s) { fStarguider = s; }
    190  
     182
     183    static TString GetFileName(const char *name);
     184
     185    MGCosy *GetWin() { return fWin; }
     186
     187    AltAz GetAltAzDeg() const
     188    {
     189        ZdAz sepos = GetSePos()*TMath::TwoPi()/kResSE;
     190        AltAz za1(TMath::Pi()/2-sepos.Zd(), sepos.Az());
     191        za1 *= kRad2Deg;
     192        return za1;
     193    }
     194
    191195    // static ZdAz CorrectTarget(const ZdAz &src, const ZdAz &dst);
    192196    //    static ZdAz RaDec2ZdAz(const double mjd, const RaDec &pos, const RaDec &pm=RaDec(0,0));
  • trunk/MagicSoft/Cosy/main/MPointing.cc

    r3935 r4076  
    7474    const int vr = mac->GetVelRes();
    7575    mac->SetAcceleration(acc*vr);
    76     mac->SetAcceleration(dec*vr);
     76    mac->SetDeceleration(dec*vr);
    7777    return !mac->IsZombieNode();
    7878}
     
    9696int MPointing::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
    9797{
    98     /*
    9998    const ZdAz d = dst*kRad2Deg;
    10099
     
    105104    // Calculate new target position (shortest distance to go)
    106105    //
    107     const ZdAz src = fCosy->GetSePos(); // [se]
     106    //const ZdAz src = fCosy->GetSePos(); // [se]
    108107
    109108    //
     
    123122    ZdAz bend = fCosy->fBending(dst); // [rad]
    124123
    125     const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
     124    const ZdAz dest = bend*fCosy->kResSE/TMath::TwoPi(); // [se]
    126125
    127126    if (!fCosy->CheckRange(bend))
     
    131130    fCosy->fZdAzSoll = dst;
    132131
    133     cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
    134     cout << "Destination   Zd: " << dst.Zd()*8192/TMath::Pi() << "se  Az:" << dst.Az()*8192/TMath::Pi()  << "se" << endl;
    135     cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
    136     cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
     132    //cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
     133    //cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
     134    //cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
     135    //cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
     136
     137    //
     138    // Set velocities
     139    //
     140    //const int vr = fCosy->fMac1->GetVelRes();
     141
     142    const Float_t rad2se = fCosy->kResSE.X()/TMath::TwoPi();
    137143
    138144    int i;
    139     for (i=0; i<(track?1:10) && !Break(); i++)
     145    for (i=0; i<(track?1:10) && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/; i++)
    140146    {
    141147
    142148        lout << "- Step #" << i << endl;
    143         //
     149
    144150        // Get Shaft Encoder Positions
    145         //
    146151        const ZdAz p=fCosy->GetSePos();
    147152
    148         //
    149153        // calculate control deviation and rounded cd
    150         //
    151154        ZdAz rd = dest-p; // [se]
    152 
    153         // ===========================================
    154         const ZdAz ist = dst-rd*TMath::Pi()/8192;
    155 
    156         const double p1 = ist.Zd()-19.0605/kRad2Deg;
    157         const double p2 = dst.Zd()-19.0605/kRad2Deg;
    158 
    159         const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
    160         const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
    161         // ===========================================
    162 
    163155        ZdAz cd = rd;     // [se]
    164156        cd.Round();
    165157
    166         //
    167158        // Check if there is a control deviation on the axis
    168         //
    169159        const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
    170160        const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
    171161
    172         //
    173162        // check if we reached the correct position already
    174         //
    175163        if (!cdzd && !cdaz)
    176164        {
     
    178166            lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
    179167            fCosy->SetStatus(MDriveCom::kStopped);
    180             fCosy->fCom->Send("POSITION DONE");
     168            fCosy->fCom->SendStatus("Target position reached.");
    181169            return TRUE;
    182170        }
    183171
    184         //
     172        // ==============================================
     173        //   Estimate the noncircularity of the zd axis
     174        const ZdAz ist = dst-rd*TMath::TwoPi()/fCosy->kResSE;
     175
     176        const double p1 = ist.Zd()-19.0605/kRad2Deg;
     177        const double p2 = dst.Zd()-19.0605/kRad2Deg;
     178
     179        const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*rad2se;
     180        const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*rad2se;
     181        // ==++=========================================
     182
    185183        // change units from se to re
    186         //
    187         rd *= fCosy->kGearRatio; // [re]
     184        rd *= fCosy->kGearTot/fCosy->kResSE; // [re]
    188185        rd.Zd(f2-f1);
    189186
    190         //
    191187        // Initialize Velocities so that we reach both positions
    192188        // at the same time
    193         //
    194         if (i)
    195         {
    196             lout << "--- LO-SPEED ---" << endl;
    197             SetAccDec(fCosy->fMac1, 0.1, 0.1);
    198             SetAccDec(fCosy->fMac2, 0.1, 0.1);
    199 
    200             SetPosVelocity(1.0, 0.05);
    201         }
    202         else
    203         {
    204             const Double_t y = 15*fCosy->kGearRatio.Y();
    205             if (rd.Az()>-y && rd.Az()<y)
    206             {
    207                 lout << "--- LO-SPEED Mac1 ---" << endl;
    208                 SetAccDec(fCosy->fMac1, 0.05, 0.05);
    209             }
    210             else
    211                 SetAccDec(fCosy->fMac1, fAcc, fDec);
    212 
    213             SetAccDec(fCosy->fMac2, fAcc, fDec);
    214 
    215             SetPosVelocity(fabs(rd.Ratio()), fVel);
    216         }
    217 
    218         rd.Round();
    219 
    220         // FIXME? Check for Error or Zombie?
    221 
    222         // cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
    223         // cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
    224         // cout << " +       dZd=" << setw(6) << cd.Zd() << "se  dAz=" << setw(6) << cd.Az() << "se" << endl;
    225         // cout << " +       dZd=" << setw(6) << rd.Zd() << "re  dAz=" << setw(6) << rd.Az() << "re" << endl;
    226         // cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
    227 
    228         //
    229         // repositioning (relative)
    230         //
    231 
    232         lout << "- Do Relative Positioning..." << endl;
    233         DoRelPos(rd, cdzd, cdaz);
    234         lout << "- Relative Positioning Done" << endl;
    235     }
    236 
    237 
    238     return FALSE;*/
    239 
    240     const ZdAz d = dst*kRad2Deg;
    241 
    242     MTime t(-1);
    243     lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
    244 
    245     //
    246     // Calculate new target position (shortest distance to go)
    247     //
    248     //const ZdAz src = fCosy->GetSePos(); // [se]
    249 
    250     //
    251     // Make sure that the motors are in sync mode (necessary if the
    252     // MACS has been rebooted from a Zombie state.
    253     //
    254     //InitSync();
    255     //if (fMac3->IsZombieNode())
    256     //    return false;
    257 
    258     //
    259     // Because we agreed on I don't search for the shortest move
    260     // anymore
    261     //
    262     // const ZdAz dest = CorrectTarget(src, dst);
    263     //
    264     ZdAz bend = fCosy->fBending(dst); // [rad]
    265 
    266     const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
    267 
    268     if (!fCosy->CheckRange(bend))
    269         return kFALSE;
    270 
    271     bend *= kRad2Deg;
    272     fCosy->fZdAzSoll = dst;
    273 
    274     //cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
    275     //cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
    276     //cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
    277     //cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
    278 
    279     //
    280     // Set velocities
    281     //
    282     //const int vr = fCosy->fMac1->GetVelRes();
    283 
    284     int i;
    285     for (i=0; i<(track?1:10) && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/; i++)
    286     {
    287 
    288         lout << "- Step #" << i << endl;
    289         //
    290         // Get Shaft Encoder Positions
    291         //
    292         const ZdAz p=fCosy->GetSePos();
    293 
    294         //
    295         // calculate control deviation and rounded cd
    296         //
    297         ZdAz rd = dest-p; // [se]
    298 
    299         // ===========================================
    300         const ZdAz ist = dst-rd*TMath::Pi()/8192;
    301 
    302         const double p1 = ist.Zd()-19.0605/kRad2Deg;
    303         const double p2 = dst.Zd()-19.0605/kRad2Deg;
    304 
    305         const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
    306         const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
    307         // ===========================================
    308 
    309         ZdAz cd = rd;     // [se]
    310         cd.Round();
    311 
    312         //
    313         // Check if there is a control deviation on the axis
    314         //
    315         const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
    316         const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
    317 
    318         //
    319         // check if we reached the correct position already
    320         //
    321         if (!cdzd && !cdaz)
    322         {
    323             t.Now();
    324             lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
    325             fCosy->SetStatus(MDriveCom::kStopped);
    326             fCosy->fCom->Send("POSITION DONE");
    327             return TRUE;
    328         }
    329 
    330         //
    331         // change units from se to re
    332         //
    333         rd *= fCosy->kGearRatio; // [re]
    334         rd.Zd(f2-f1);
    335 
    336         //
    337         // Initialize Velocities so that we reach both positions
    338         // at the same time
    339         //
    340 /*        if (i)
    341         {
    342             fCosy->fMac1->SetAcceleration(0.1*vr);
    343             fCosy->fMac2->SetAcceleration(0.1*vr);
    344 
    345             fCosy->fMac1->SetDeceleration(0.1*vr);
    346             fCosy->fMac2->SetDeceleration(0.1*vr);
    347 
    348             fCosy->SetPosVelocity(1.0, 0.05);
    349         }
    350         else
    351         {
    352             if (rd.Az()>-15*fCosy->kGearRatio.Y() && rd.Az()<15*fCosy->kGearRatio.Y())
    353             {
    354 #ifdef EXPERT
    355                 cout << " -------------- LO ---------------- " << endl;
    356 #endif
    357                 fCosy->fMac1->SetAcceleration(0.05*vr);
    358                 fCosy->fMac1->SetDeceleration(0.05*vr);
    359             }
    360             else
    361             {
    362 #ifdef EXPERT
    363                 cout << " -------------- HI ---------------- " << endl;
    364                 fCosy->fMac1->SetAcceleration(0.4*vr);// 0.4
    365                 fCosy->fMac1->SetDeceleration(0.4*vr);// 0.4
    366 #else
    367                 fCosy->fMac1->SetAcceleration(0.2*vr);
    368                 fCosy->fMac1->SetDeceleration(0.1*vr);
    369 #endif
    370             }
    371 
    372 #ifdef EXPERT
    373             fCosy->fMac2->SetAcceleration(0.4*vr);// 0.4
    374             fCosy->fMac2->SetDeceleration(0.4*vr);// 0.4
    375             fCosy->SetPosVelocity(fabs(rd.Ratio()), 0.2); // fast: 0.6, slow: 0.2
    376 #else
    377             fCosy->fMac2->SetAcceleration(0.2*vr);
    378             fCosy->fMac2->SetDeceleration(0.1*vr);
    379             fCosy->SetPosVelocity(fabs(rd.Ratio()), 0.1);
    380 #endif
    381         }
    382         */
    383189        if (i)
    384190        {
     
    391197        else
    392198        {
    393             const Double_t y = 15*fCosy->kGearRatio.Y();
     199            const Double_t y = 15*fCosy->kGearTot.Y()*fCosy->kResSE.Y();
    394200            if (rd.Az()>-y && rd.Az()<y)
    395201            {
     
    409215        // FIXME? Check for Error or Zombie?
    410216
    411 
    412217        // cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
    413218        // cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
     
    416221        // cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
    417222
    418 
    419         //
    420223        // repositioning (relative)
    421         //
    422224        lout << "- Do Relative Positioning..." << endl;
    423225        DoRelPos(rd, cdzd, cdaz);
     
    429231        lout << t << " - Positioning done." << endl;
    430232        fCosy->SetStatus(MDriveCom::kStopped);
    431         fCosy->fCom->Send("POSITION DONE");
     233        fCosy->fCom->SendStatus("Tracking preposition reached.");
    432234        return TRUE;
    433235    }
     
    441243    lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
    442244
    443     fCosy->fCom->Send("POSITION FAILED");
     245    fCosy->fCom->SendStatus("Target position missed!");
    444246
    445247    return FALSE;
  • trunk/MagicSoft/Cosy/main/MTracking.cc

    r3935 r4076  
    1313//#define EXPERT
    1414#undef EXPERT
     15
     16// --------------------------------------------------------------------------
     17//
     18// request the current positions from the rotary encoders.
     19// use GetRePos to get the psotions. If the request fails the function
     20// returns kFALSE, otherwise kTRUE
     21//
     22bool MTracking::RequestRePos()
     23{
     24    //
     25    // Send request
     26    //
     27    fCosy->fMac2->RequestSDO(0x6004);
     28    fCosy->fMac1->RequestSDO(0x6004);
     29
     30    //
     31    // Wait until the objects are received.
     32    //
     33    fCosy->fMac2->WaitForSdo(0x6004);
     34    fCosy->fMac1->WaitForSdo(0x6004);
     35
     36    //
     37    // If waiting was not interrupted everything is ok. return.
     38    //
     39    if (!Break())
     40        return true;
     41
     42    //
     43    // If the waiting was interrupted due to a network error,
     44    // print some logging message.
     45    //
     46    if (fCosy->HasError())
     47        lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
     48
     49    return false;
     50}
    1551
    1652// --------------------------------------------------------------------------
     
    4985    return true;
    5086}
    51 
     87/*
     88void MTracking::StopTracking()
     89{
     90    //
     91    // Set status to Stopping
     92    //
     93    fCosy->SetStatus(MDriveCom::kStopping);
     94
     95    //
     96    // set deceleration to 50%
     97    //
     98    cout << "Stopping tracking (dec=20%)..." << endl;
     99    fCosy->fMac1->SetDeceleration(0.2*fMac1->GetVelRes());
     100    fCosy->fMac2->SetDeceleration(0.2*fMac2->GetVelRes());
     101
     102    fCosy->fMac2->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
     103    fCosy->fMac1->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
     104    fCosy->fMac2->WaitForSdo(0x3006, 1);
     105    fCosy->fMac1->WaitForSdo(0x3006, 1);
     106
     107    cout << "Waiting for end of movement..." << endl;
     108    fCosy->WaitForEndMovement();
     109
     110    //
     111    // Wait for the objects to be OKed.
     112    //
     113    fCosy->fMac1->SetRpmMode(FALSE);
     114    fCosy->fMac2->SetRpmMode(FALSE);
     115
     116    //
     117    // Wait for the movement to really be finished.
     118    //
     119    //cout << "Waiting for end of movement..." << endl;
     120    //WaitForEndMovement();
     121
     122    //
     123    // Check whether everything works fine.
     124    //
     125    fCosy->CheckForError();
     126    cout << "Movement stopped." << endl;
     127}
     128*/
    52129// --------------------------------------------------------------------------
    53130//
     
    58135// velocities are limited to the maximum velocity.
    59136//
    60 Bool_t MTracking::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
    61 {
     137Bool_t MTracking::LimitSpeed(ZdAz *vt, const SlaStars &sla) const
     138{
     139    // vt[re/min]
     140
     141    // Calculate approximate velocity of both axis
     142    ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec);  // [rad/rad]
     143
     144    //vcalc *= 1./(24*60);          // [U_tel/min]
     145    //vcalc *= fCosy->kGearTot; // [U_mot/min]
     146    //vcalc *= fCosy->kResRE;   // [re/min]
     147
     148    vcalc *= fCosy->kGearTot*fCosy->kResRE/(24*60); // [re/min]
     149
     150    // Set return code
    62151    Bool_t rc = kFALSE;
    63152
     
    83172    const Float_t maxtrack = 0.1;
    84173
    85     if (fabs(vt->Az()) > maxtrack*vraz)
    86     {
     174    if (fabs(vt->Az()) > maxtrack*vraz*4)
     175    {
     176        vt->Az(maxtrack*vraz*4*sgn(vcalc.Az()));
    87177        lout << "Warning: Azimuth speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Az()) << " > " << maxtrack*vraz << ")... limited." << endl;
    88         vt->Az(maxtrack*vraz*sgn(vcalc.Az()));
     178        lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
    89179        rc=kTRUE;
    90180    }
    91     if (fabs(vt->Zd()) > maxtrack*vrzd)
    92     {
     181    if (fabs(vt->Zd()) > maxtrack*vrzd*4)
     182    {
     183        vt->Zd(maxtrack*vrzd*4*sgn(vcalc.Zd()));
    93184        lout << "Warning: Altitude speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Zd()) <<" > " << maxtrack*vrzd << ")... limited." << endl;
    94         vt->Zd(maxtrack*vrzd*sgn(vcalc.Zd()));
     185        lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
    95186        rc=kTRUE;
    96187    }
     
    146237    lout << sla.GetTime() << ": Track Position " << dst.Ra()*kRad2Deg/15 << "h, " << dst.Dec()*kRad2Deg <<"deg" << endl;
    147238
    148     // az between -180 and 180
    149     if (dst.Dec()>sla.GetPhi() && dest.Az()<0)
    150     {
    151         // align az between (roughly) 60 and 320
    152         lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
    153         dest.Az(dest.Az() + TMath::Pi()*2);
    154     }
    155 /*
    156     // FIXME: Determin tracking start point by star culmination
    157     if (dest.Az()<-TMath::Pi()/2)
    158     {
    159         lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
    160         dest.Az(dest.Az() + TMath::Pi()*2);
    161     }
    162 
    163     if (dest.Az()>3*TMath::Pi()/2)
    164     {
    165         lout << "Substracting 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
    166         dest.Az(dest.Az() -TMath::Pi()*2);
    167     }
    168  */
     239    // If the star is culminating behind the zenith (South) we want to
     240    // align the azimuth angle between -180 and 180deg. If the star is
     241    // culminating before the zenith (north) we want the star to be
     242    // aligned between -180 and 180deg (which is the default of CalcZdAz)
     243    if (sla.GetPhi()>dst.Dec() && dest.Az()<0)
     244    {
     245        // align az from -180/180 to 0/360
     246        lout << "Star culminating behind zenith: Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
     247        dest.Az(dest.Az() + TMath::TwoPi());
     248    }
     249
     250    // Position the telescope to the current local position of the
     251    // star. Do not reposition but start the tracking after the
     252    // first positioning step
    169253    if (!SetPosition(dest, kTRUE))
    170     //if (!SetPosition(dest, kFALSE))
    171254    {
    172255        lout << "Error: Cannot start tracking, positioning failed." << endl;
     
    177260    // calculate offset from present se position
    178261    //
    179     const ZdAz sepos = fCosy->GetSePos()*fCosy->kGearRatio;
    180 
    181     if (!fCosy->RequestRePos())
     262    const ZdAz sepos = fCosy->GetSePos()*fCosy->kGearTot/fCosy->kResSE; //[re]
     263    if (!RequestRePos())
    182264        return;
    183265
     
    185267    // Estimate Offset before starting to track
    186268    //
    187     fCosy->fOffset = sepos-fCosy->GetRePos();
     269    fOffset = sepos-fCosy->GetRePos();
    188270
    189271    /*
     
    202284    }
    203285
    204     XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
    205 
    206     sla.Now();
    207 //    lout << sla.GetTime() << " - Start tracking:";
    208 //    lout << " Ra: " << xy.X() << "h  " << "Dec: " << xy.Y() << "\xb0" << endl;
    209 
    210 /*#ifdef EXPERT
    211     ofstream fout("coordinates.txt");
    212     fout << xy;
    213     fout.close();
    214 #endif
    215 */    //
    216286    // Initialize Tracker (slalib or starguider)
    217     //
    218287    fCosy->fRaDec = dst;
    219288
     
    221290    Start();
    222291
     292    // Get current nominal local position
     293    sla.Now();
    223294    ZdAz pos = sla.CalcZdAz(fCosy->fRaDec);
    224295
     296    // Some output
     297    XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
    225298    lout << sla.GetTime() << " - Start Tracking: Ra=" <<xy.X() << "h Dec=";
    226299    lout << xy.Y() << "\xb0 @ Zd=" << pos.Zd()*kRad2Deg <<"deg Az=" << pos.Az()*kRad2Deg <<"deg" << endl;
    227 
    228 //---    ofstream fout("log/cosy.pos");
    229 //---    fout << "Tracking:";
    230 //---    fout << " Ra: " << Rad2Deg(dst.Ra())  << "\x9c  ";
    231 //---    fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
    232 //---    fout << "     Mjd/10ms    V/re/min/4" << endl;
    233300
    234301    //
     
    240307    {
    241308        //
    242         // Request Target position for this moment
     309        // Request Target position for Now+dt
    243310        //
    244311        sla.Now(dt);
    245312
    246313        //
    247         // Request theoretical Position for a time in the future (To+dt) from CPU
    248         //
    249         const ZdAz pointing = sla.CalcZdAz(fCosy->fRaDec); // soll pointing [rad]
    250 
    251         //lout << sla.GetTime() << pointing.Zd()*kRad2Deg << " " << pointing.Az()*kRad2Deg << endl;
    252         /*
    253         ZdAz dest;
    254         if (!AlignTrackingPos(pointing, dest))
    255             break;
    256             */
    257         ZdAz dest = fCosy->AlignTrackingPos(pointing);
    258 
    259         // lout << "DEST: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
    260 
    261         ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec) * fCosy->kGearRatio2*4./60.;
    262         //lout << "Vcalc: " << dest.Zd() << " " << dest.Az() << endl;
    263         vcalc *= fCosy->kGearRatio2*4./60.; // [re/min]
     314        // Request nominal position for this time in the future (To+dt)
     315        //
     316        const ZdAz pointing = sla.CalcZdAz(fCosy->fRaDec); // [rad]
     317        ZdAz dest = fCosy->AlignTrackingPos(pointing);     // fix ambiguity
     318
     319        //ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec);
     320        //vcalc *= fCosy->kGearRatio2*4./60.; // [re/min]
    264321
    265322        float dtime = -1;
     
    267324        //    dtime = Starguider(sla.GetMjd(), dest);
    268325
     326        ZdAz repos;
    269327        if (dtime<0)
    270328        {
    271             dest = fCosy->fBending(dest);       // [rad]
    272 
    273             //lout << "DEST-BEND: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
    274              
     329            dest = fCosy->fBending(dest);            // [rad]
    275330            if (!fCosy->CheckRange(dest))
    276331                break;
    277332
    278             dest *= 16384/TMath::Pi()/2; // [se]
    279             dest *= fCosy->kGearRatio;          // [re]
    280 
    281             *fCosy->fOutRep << "> ReqRePos1 " << endl;
     333            dest *= fCosy->kGearTot/TMath::TwoPi();  // [re]
     334
     335            //*fCosy->fOutRep << "> ReqRePos1 " << endl;
    282336
    283337            //
    284338            // Request absolute position of rotary encoder from Macs
    285339            //
    286             if (!fCosy->RequestRePos())
     340            if (!RequestRePos())
    287341                break;
    288342
    289             *fCosy->fOutRep << "> ReqRePos2 " << endl;
     343            //*fCosy->fOutRep << "> ReqRePos2 " << fOffset.Zd() << " " << fOffset.Az() << endl;
    290344
    291345            //
     
    294348            // fOffset does the synchronization between the
    295349            // Shaft- and the rotary encoders
    296             dest -= fCosy->GetRePos() + fCosy->fOffset;
     350            repos = fCosy->GetRePos();
     351            dest -= repos + fOffset; //[re]
    297352
    298353            dtime = dt;
    299 
    300             ZdAz repos = fCosy->GetRePos();
    301     //        lout << "Repos: " << repos.Zd()/kGearRatio.X() << " " << repos.Az()*kGearRatio.Y() << endl;
    302    //         repos /= kGearRatio;
    303             repos /= 16384/TMath::Pi()/2;
    304             repos *= kRad2Deg;
    305354        }
    306355
     
    309358        // correct for the duration of RaDec2AltAz
    310359        //
    311         const ZdAz v = dest*60.0/(dtime/*-(fMac2->GetTime()-sla)*/);
     360        /* --- OLD --- */
     361        ZdAz v = dest*60.0/dtime; //[re/min]
     362        /* --- NEW --- seems to work worse! */
     363        //const Double_t dtaz = sla.GetTime() - fCosy->fMac1->GetPosTime();
     364        //const Double_t dtzd = sla.GetTime() - fCosy->fMac2->GetPosTime();
     365        //
     366        //ZdAz v = dest*60.0;
     367        //v.Zd(v.Zd()/dtzd);
     368        //v.Az(v.Az()/dtaz);
     369        /* --- END --- */
     370
     371        //*fCosy->fOutRep << "> Dt:  " << dtaz << "  " << dtzd << endl;
     372
     373        if (LimitSpeed(&v, sla))
     374        {
     375            lout << "vt: " << v.Zd() << " " << v.Az() << "re/min" << endl;
     376            lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
     377        }             
    312378
    313379        //
     
    315381        // believing the Macs manual '/4' shouldn't be necessary, but it is.
    316382        //
    317         ZdAz vt = v/4;
    318         if (LimitSpeed(&vt, vcalc))
    319         {
    320             lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
    321             lout << "vt: " << vt.Zd() << " " << vt.Az() << "re/min" << endl;
    322             lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
    323         }             
     383        ZdAz vt = v/4; //[re'/min]
     384        //lout << " " << vt.Zd() << " " << vt.Az() << " ";
    324385        vt.Round();
     386        //lout << " " << vt.Zd() << " " << vt.Az() << endl;
    325387
    326388        //
     
    337399        // Maybe we should attenuate the changes
    338400        //
    339         *fCosy->fOutRep << "> SetVelocity1 " << endl;
     401        //*fCosy->fOutRep << "> SetVelocity1:  " << vt.Zd() << "  " << vt.Az() << endl;
    340402        if (!SetVelocity(vt))
    341403            break;
    342         *fCosy->fOutRep << "> SetVelocity2 " << endl;
    343 
    344         //
    345         // Now do 'unnecessary' things
    346         //
    347         fCosy->fVelocity = vt/fCosy->kGearRatio2*4;
    348 
    349 //---        const double mjd = fMac2->GetMjd();
    350 //---        fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
    351 //---        fout << setw(4) << vt.Zd() << " ";
    352 //---        fout << setw(4) << vt.Az() << endl;
    353         //
    354         // FIXME? Calculate an accuracy for the tracking system?
    355         // How good do we reach the calculated position in 'real'
    356         // re valus?
    357         //
    358 
     404        //*fCosy->fOutRep << "> SetVelocity2 " << endl;
     405
     406        //
     407        // Now do 'unnecessary' things (timing)
     408        //
     409        fCosy->fVelocity = vt*4/fCosy->kGear; // [U_mot/min]
     410        // *OLD* fVelocity = vt/kGearRatio2*4;
     411
     412        if (fOut)
     413        {
     414            fOut->Lock();
     415            *fOut << "RE-REPORT " << MTime(-1) << " " << repos.Zd() << " " << repos.Az() <<" " << vt.Zd() << " " << vt.Az() << endl;
     416            fOut->UnLock();
     417        }
    359418
    360419        //
     
    363422        // update time
    364423        //
    365         //
    366424        // The loop should not be executed faster than the ramp of
    367425        // a change in the velocity can be followed.
    368426        // (This is important on fast machines >500MHz)
    369427        //
    370         /*
    371         MTimeout t(1000);
    372         while (!t.HasTimedOut())
    373             usleep(1);
    374          */
    375428        usleep(1000000); // 1s
    376         cout << "." << flush;
    377         //usleep(50000); // 0.05s
     429// *****FIXME****        cout << "." << flush;
    378430    }
    379431
     
    385437    fCosy->StopMovement();
    386438
    387     lout << sla.GetTime() << " - Tracking stopped." << endl;
     439    lout << sla.GetTime() << " - Tracking stopped @ Zd=";
     440    lout << fCosy->fZdAzSoll.Zd()*TMath::RadToDeg() <<"deg Az=";
     441    lout << fCosy->fZdAzSoll.Az()*TMath::RadToDeg() <<"deg" << endl;
    388442}
    389443
     
    401455    lout << "- Tracking Thread started..." << endl;
    402456
     457    const XY re2se = fCosy->kGearTot/fCosy->kResSE; //[re/se]
     458
    403459    SlaStars sla(fCosy->fObservatory);
    404460    sla.Now();
    405461
    406     ZdAz old;
    407     ZdAz ist = fCosy->GetSePos();              // [se]
    408 
    409462    ZdAz time;
    410463
    411     ZdAz sollzd = sla.CalcZdAz(fCosy->fRaDec); // [rad]
    412     ZdAz sollaz = sollzd;               // [rad]
     464    ZdAz soll = sla.CalcZdAz(fCosy->fRaDec); // [rad]
    413465
    414466    //
     
    421473    while (!HasStopFlag())
    422474    {
    423         //
    424475        // Make changes (eg wind) smoother - attenuation of control function
    425         //
    426         const float weight = 1.; //0.3;
    427 
    428         //
    429476        // This is the time constant which defines how fast
    430477        // you correct for external influences (like wind)
    431         //
    432         *fCosy->fOutRep << "> ResetPosHasChanged" << endl;
     478        const float weight = 1.; //0.3;
     479
     480        // Check for changes of the shaftencoder values
     481        //*fCosy->fOutRep << "> ResetPosHasChanged" << endl;
    433482        fCosy->fZd1->ResetPosHasChanged();
    434483        fCosy->fZd2->ResetPosHasChanged();
    435484        fCosy->fAz->ResetPosHasChanged();
    436         *fCosy->fOutRep << "> Check for PosHasChanged" << endl;
     485        //*fCosy->fOutRep << "> Check for PosHasChanged" << endl;
    437486        do
    438487        {
     
    443492        } while (!phca1 && !phca2 && !phcaz && !HasStopFlag());
    444493
    445         //---usleep(100000); // 0.1s
    446 
    447         *fCosy->fOutRep << "> Do Calculation" << endl;
    448 
    449         //
    450         // get position, where we are
    451         //
    452         old = ist;
    453         ist = fCosy->GetSePos(); // [se]
    454 
    455         //
    456         // if the position didn't change continue
    457         //
    458         /*---
    459          if ((int)ist.Zd() == (int)old.Zd() &&
    460          (int)ist.Az() == (int)old.Az())
    461          continue;
    462          */
     494        //*fCosy->fOutRep << "> Do Calculation" << endl;
     495
     496        // Get current position of motors (use last automatically sent
     497        // position (PDO) - requesting the position results in problems
     498        // with thread safty)
    463499        ZdAz istre = fCosy->GetRePosPdo();
    464500
    465         //
     501        // get current position of shaftencoders
     502        ZdAz istse = fCosy->GetSePos(); // [se]
     503
    466504        // Get time from last shaftencoder position change (position: ist)
    467         // FIXME: I cannot take the avarage
    468         //
    469         // FIXME
    470         //time.Zd(fZd1->GetMjd());
    471         /* OLD* */
     505        // FIXME: Is this correct?
    472506        if (fCosy->fZd1->GetMjd()>fCosy->fZd2->GetMjd())
    473507            time.Zd(fCosy->fZd1->GetMjd());
     
    475509            time.Zd(fCosy->fZd2->GetMjd());
    476510
    477         //time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
    478511        time.Az(fCosy->fAz->GetMjd());
    479512
    480         //
    481         // if Shaftencoder changed position
    482         // calculate were we should be
    483         //
    484         if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
    485         {
    486             sollzd = sla.CalcZdAz(fCosy->fRaDec, time.Zd()); // [rad]
    487             /*
    488             ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
    489             sollzd = CorrectTarget(ist, dummy); // [se]
    490             */
    491             fCosy->fOffset.Zd(fCosy->fOffset.Zd()*(1.-weight)+(ist.Zd()*fCosy->kGearRatio.X()-istre.Zd())*weight);
     513        // calculate offset for both axis (only one is needed)
     514        const ZdAz offset = (istse*re2se - istre)*weight + fOffset*(weight-1);
     515
     516        // if Shaftencoder changed position, calculate nominal position
     517        if (phca1 || phca2)
     518        {
     519            const ZdAz dummy = sla.CalcZdAz(fCosy->fRaDec, time.Zd());
     520            soll.Zd(dummy.Zd()); // [rad]
     521            fOffset.Zd(offset.Zd());
    492522        }
    493 
    494         if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
    495         {
    496             sollaz = sla.CalcZdAz(fCosy->fRaDec, time.Az()); // [rad]
    497             /*
    498             ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
    499             sollaz = CorrectTarget(ist, dummy); // [se]
    500             */
    501             fCosy->fOffset.Az(fCosy->fOffset.Az()*(1.-weight)+(ist.Az()*fCosy->kGearRatio.Y()-istre.Az())*weight);
     523        if (phcaz)
     524        {
     525            const ZdAz dummy = sla.CalcZdAz(fCosy->fRaDec, time.Az());
     526            soll.Az(dummy.Az()); // [rad]
     527            fOffset.Az(offset.Az());
    502528        }
    503529
    504         ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad]
    505 
     530        // After calculation of fOffset is done we need 'ist' in rad
     531        istse /= fCosy->kResSE/TMath::TwoPi(); // [rad]
     532
     533        // Calculate the aligned tracking posotion from 'soll'-position
    506534        fCosy->fZdAzSoll = fCosy->AlignTrackingPos(soll);
    507535
    508         ist *= TMath::Pi()*2/16384;
    509         soll = fCosy->fBending(fCosy->fZdAzSoll);
    510         fCosy->fTrackingError.Set(ist.Zd()-soll.Zd(), ist.Az()-soll.Az());
    511 
    512         //---            fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
    513         //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Zd() << "  ";
    514         //---            fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
    515         //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Az() << endl;
     536        /* --- OLD --- */
     537        //fCosy->fTrackingError = istse-fCosy->fBending(fCosy->fZdAzSoll);
     538        /* --- NEW --- */
     539        fCosy->fTrackingError = fCosy->fBending.CorrectBack(istse)-fCosy->fZdAzSoll;
     540        /* --- END --- */
    516541    }
    517542
  • trunk/MagicSoft/Cosy/main/MTracking.h

    r3935 r4076  
    11#ifndef COSY_MTracking
    22#define COSY_MTracking
     3
     4#include "coord.h"
    35
    46#ifndef COSY_MPointing
     
    1012#endif
    1113
     14class SlaStars;
     15
    1216class MTracking : public MPointing, public MThread
    1317{
     
    1620    Float_t fTrackDec;
    1721
     22    ZdAz    fOffset; // Offset between se and re coordinate system [re]
     23
     24    MLog *fOut;
     25
     26    bool RequestRePos();
    1827    bool SetVelocity(const ZdAz &v);
     28    bool LimitSpeed(ZdAz *vt, const SlaStars &sla) const;
    1929    bool InitTracking();
    20     bool LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const;
     30    //void StopTracking();
    2131
    2232    void *Thread();
    2333
    2434public:
    25     MTracking(MCosy *cosy, const Log &log) : MPointing(cosy, log), MThread(kFALSE), fTrackAcc(0.1), fTrackDec(0.1) { }
     35    MTracking(MCosy *cosy, const Log &log) : MPointing(cosy, log), MThread(kFALSE), fTrackAcc(0.1), fTrackDec(0.1), fOut(0) { }
    2636
    2737    void TrackPosition(const RaDec &dst); // ra, dec [rad]
    2838    void SetTrackAccDec(Float_t acc, Float_t dec) { fTrackAcc=0.1; fTrackDec=0.1; }
    2939
     40    void SetOut(MLog *fout) { fOut = fout; }
    3041    //void TalkThreadTracking();
    3142 
Note: See TracChangeset for help on using the changeset viewer.