Esempio n. 1
0
bool ScopeSim::ReadScopeStatus()
{
    static struct timeval ltv { 0, 0 };
    struct timeval tv { 0, 0 };
    double dt = 0, da_ra = 0, da_dec = 0, dx = 0, dy = 0, ra_guide_dt = 0, dec_guide_dt = 0;
    static double last_dx = 0, last_dy = 0;
    int nlocked, ns_guide_dir = -1, we_guide_dir = -1;
    char RA_DISP[64], DEC_DISP[64], RA_GUIDE[64], DEC_GUIDE[64], RA_PE[64], DEC_PE[64], RA_TARGET[64], DEC_TARGET[64];

    /* update elapsed time since last poll, don't presume exactly POLLMS */
    gettimeofday(&tv, nullptr);

    if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
        ltv = tv;

    dt  = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
    ltv = tv;

    if (fabs(targetRA - currentRA) * 15. >= GOTO_LIMIT)
        da_ra = GOTO_RATE * dt;
    else if (fabs(targetRA - currentRA) * 15. >= SLEW_LIMIT)
        da_ra = SLEW_RATE * dt;
    else
        da_ra = FINE_SLEW_RATE * dt;

    if (fabs(targetDEC - currentDEC) >= GOTO_LIMIT)
        da_dec = GOTO_RATE * dt;
    else if (fabs(targetDEC - currentDEC) >= SLEW_LIMIT)
        da_dec = SLEW_RATE * dt;
    else
        da_dec = FINE_SLEW_RATE * dt;

    if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY)
    {
        int rate = IUFindOnSwitchIndex(&SlewRateSP);

        switch (rate)
        {
            case SLEW_GUIDE:
                da_ra  = FINE_SLEW_RATE * dt * 0.05;
                da_dec = FINE_SLEW_RATE * dt * 0.05;
                break;

            case SLEW_CENTERING:
                da_ra  = FINE_SLEW_RATE * dt * .1;
                da_dec = FINE_SLEW_RATE * dt * .1;
                break;

            case SLEW_FIND:
                da_ra  = SLEW_RATE * dt;
                da_dec = SLEW_RATE * dt;
                break;

            default:
                da_ra  = GOTO_RATE * dt;
                da_dec = GOTO_RATE * dt;
                break;
        }

        switch (MovementNSSP.s)
        {
            case IPS_BUSY:
                if (MovementNSS[DIRECTION_NORTH].s == ISS_ON)
                    currentDEC += da_dec;
                else if (MovementNSS[DIRECTION_SOUTH].s == ISS_ON)
                    currentDEC -= da_dec;
                break;

            default:
                break;
        }

        switch (MovementWESP.s)
        {
            case IPS_BUSY:

                if (MovementWES[DIRECTION_WEST].s == ISS_ON)
                    currentRA += da_ra / 15.;
                else if (MovementWES[DIRECTION_EAST].s == ISS_ON)
                    currentRA -= da_ra / 15.;
                break;

            default:
                break;
        }

        NewRaDec(currentRA, currentDEC);
        return true;
    }

    /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */
    switch (TrackState)
    {
        /*case SCOPE_IDLE:
            EqNP.s = IPS_IDLE;
            break;*/
        case SCOPE_SLEWING:
        case SCOPE_PARKING:
            /* slewing - nail it when both within one pulse @ SLEWRATE */
            nlocked = 0;

            dx = targetRA - currentRA;

            // Always take the shortcut, don't go all around the globe
            // If the difference between target and current is more than 12 hours, then we need to take the shortest path
            if (dx > 12)
                dx -= 24;
            else if (dx < -12)
                dx += 24;

            // In meridian flip, alway force eastward motion (increasing RA) until target is reached.
            if (forceMeridianFlip)
            {
                dx = fabs(dx);
                if (dx == 0)
                {
                    dx    = 1;
                    da_ra = GOTO_LIMIT;
                }
            }

            if (fabs(dx) * 15. <= da_ra)
            {
                currentRA = targetRA;
                nlocked++;
            }
            else if (dx > 0)
                currentRA += da_ra / 15.;
            else
                currentRA -= da_ra / 15.;

            currentRA = range24(currentRA);

            dy = targetDEC - currentDEC;
            if (fabs(dy) <= da_dec)
            {
                currentDEC = targetDEC;
                nlocked++;
            }
            else if (dy > 0)
                currentDEC += da_dec;
            else
                currentDEC -= da_dec;

            EqNP.s = IPS_BUSY;

            if (nlocked == 2)
            {
                forceMeridianFlip = false;

                if (TrackState == SCOPE_SLEWING)
                {
                    // Initially no PE in both axis.
                    EqPEN[0].value = currentRA;
                    EqPEN[1].value = currentDEC;

                    IDSetNumber(&EqPENV, nullptr);

                    TrackState = SCOPE_TRACKING;

                    EqNP.s = IPS_OK;
                    DEBUG(INDI::Logger::DBG_SESSION, "Telescope slew is complete. Tracking...");
                }
                else
                {
                    SetParked(true);
                    EqNP.s = IPS_IDLE;
                }
            }

            break;

        case SCOPE_IDLE:
                 //currentRA += (TRACKRATE_SIDEREAL/3600.0 * dt) / 15.0;
                currentRA += (TrackRateN[AXIS_RA].value/3600.0 * dt) / 15.0;
                currentRA = range24(currentRA);
        break;

        case SCOPE_TRACKING:
            // In case of custom tracking rate
            if (TrackModeS[1].s == ISS_ON)
            {
                currentRA  += ( ((TRACKRATE_SIDEREAL/3600.0) - (TrackRateN[AXIS_RA].value/3600.0)) * dt) / 15.0;
                currentDEC += ( (TrackRateN[AXIS_DE].value/3600.0) * dt);
            }

            dt *= 1000;

            if (guiderNSTarget[GUIDE_NORTH] > 0)
            {
                DEBUGF(INDI::Logger::DBG_DEBUG, "Commanded to GUIDE NORTH for %g ms", guiderNSTarget[GUIDE_NORTH]);
                ns_guide_dir = GUIDE_NORTH;
            }
            else if (guiderNSTarget[GUIDE_SOUTH] > 0)
            {
                DEBUGF(INDI::Logger::DBG_DEBUG, "Commanded to GUIDE SOUTH for %g ms", guiderNSTarget[GUIDE_SOUTH]);
                ns_guide_dir = GUIDE_SOUTH;
            }

            // WE Guide Selection
            if (guiderEWTarget[GUIDE_WEST] > 0)
            {
                we_guide_dir = GUIDE_WEST;
                DEBUGF(INDI::Logger::DBG_DEBUG, "Commanded to GUIDE WEST for %g ms", guiderEWTarget[GUIDE_WEST]);
            }
            else if (guiderEWTarget[GUIDE_EAST] > 0)
            {
                we_guide_dir = GUIDE_EAST;
                DEBUGF(INDI::Logger::DBG_DEBUG, "Commanded to GUIDE EAST for %g ms", guiderEWTarget[GUIDE_EAST]);
            }

            if (ns_guide_dir != -1)
            {
                dec_guide_dt = TrackRateN[AXIS_RA].value/3600.0 * GuideRateN[DEC_AXIS].value * guiderNSTarget[ns_guide_dir] / 1000.0 *
                               (ns_guide_dir == GUIDE_NORTH ? 1 : -1);

                // If time remaining is more that dt, then decrement and
                if (guiderNSTarget[ns_guide_dir] >= dt)
                    guiderNSTarget[ns_guide_dir] -= dt;
                else
                    guiderNSTarget[ns_guide_dir] = 0;

                if (guiderNSTarget[ns_guide_dir] == 0)
                {
                    GuideNSNP.s = IPS_IDLE;
                    IDSetNumber(&GuideNSNP, nullptr);
                }

                EqPEN[DEC_AXIS].value += dec_guide_dt;
            }

            if (we_guide_dir != -1)
            {
                ra_guide_dt = (TrackRateN[AXIS_RA].value/3600.0) / 15.0 * GuideRateN[RA_AXIS].value * guiderEWTarget[we_guide_dir] / 1000.0 *
                              (we_guide_dir == GUIDE_WEST ? -1 : 1);

                if (guiderEWTarget[we_guide_dir] >= dt)
                    guiderEWTarget[we_guide_dir] -= dt;
                else
                    guiderEWTarget[we_guide_dir] = 0;

                if (guiderEWTarget[we_guide_dir] == 0)
                {
                    GuideWENP.s = IPS_IDLE;
                    IDSetNumber(&GuideWENP, nullptr);
                }

                EqPEN[RA_AXIS].value += ra_guide_dt;
            }

            //Mention the followng:
            // Current RA displacemet and direction
            // Current DEC displacement and direction
            // Amount of RA GUIDING correction and direction
            // Amount of DEC GUIDING correction and direction

            dx = EqPEN[RA_AXIS].value - targetRA;
            dy = EqPEN[DEC_AXIS].value - targetDEC;
            fs_sexa(RA_DISP, fabs(dx), 2, 3600);
            fs_sexa(DEC_DISP, fabs(dy), 2, 3600);

            fs_sexa(RA_GUIDE, fabs(ra_guide_dt), 2, 3600);
            fs_sexa(DEC_GUIDE, fabs(dec_guide_dt), 2, 3600);

            fs_sexa(RA_PE, EqPEN[RA_AXIS].value, 2, 3600);
            fs_sexa(DEC_PE, EqPEN[DEC_AXIS].value, 2, 3600);

            fs_sexa(RA_TARGET, targetRA, 2, 3600);
            fs_sexa(DEC_TARGET, targetDEC, 2, 3600);

            if (dx != last_dx || dy != last_dy || ra_guide_dt != 0.0 || dec_guide_dt != 0.0)
            {
                last_dx = dx;
                last_dy = dy;
                //DEBUGF(INDI::Logger::DBG_DEBUG, "dt is %g\n", dt);
                DEBUGF(INDI::Logger::DBG_DEBUG, "RA Displacement (%c%s) %s -- %s of target RA %s", dx >= 0 ? '+' : '-',
                       RA_DISP, RA_PE, (EqPEN[RA_AXIS].value - targetRA) > 0 ? "East" : "West", RA_TARGET);
                DEBUGF(INDI::Logger::DBG_DEBUG, "DEC Displacement (%c%s) %s -- %s of target RA %s", dy >= 0 ? '+' : '-',
                       DEC_DISP, DEC_PE, (EqPEN[DEC_AXIS].value - targetDEC) > 0 ? "North" : "South", DEC_TARGET);
                DEBUGF(INDI::Logger::DBG_DEBUG, "RA Guide Correction (%g) %s -- Direction %s", ra_guide_dt, RA_GUIDE,
                       ra_guide_dt > 0 ? "East" : "West");
                DEBUGF(INDI::Logger::DBG_DEBUG, "DEC Guide Correction (%g) %s -- Direction %s", dec_guide_dt, DEC_GUIDE,
                       dec_guide_dt > 0 ? "North" : "South");
            }

            if (ns_guide_dir != -1 || we_guide_dir != -1)
                IDSetNumber(&EqPENV, nullptr);

            break;

        default:
            break;
    }

    char RAStr[64], DecStr[64];

    fs_sexa(RAStr, currentRA, 2, 3600);
    fs_sexa(DecStr, currentDEC, 2, 3600);

    DEBUGF(DBG_SCOPE, "Current RA: %s Current DEC: %s", RAStr, DecStr);

    NewRaDec(currentRA, currentDEC);
    return true;
}
Esempio n. 2
0
void SynscanDriver::mountSim()
{
    static struct timeval ltv;
    struct timeval tv;
    double dt, da, dx;
    int nlocked;

    /* update elapsed time since last poll, don't presume exactly POLLMS */
    gettimeofday(&tv, nullptr);

    if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
        ltv = tv;

    dt  = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec) / 1e6;
    ltv = tv;
    double currentSlewRate = SIM_SLEW_RATE[IUFindOnSwitchIndex(&SlewRateSP)] * TRACKRATE_SIDEREAL / 3600.0;
    da  = currentSlewRate * dt;

    /* Process per current state. We check the state of EQUATORIAL_COORDS and act acoordingly */
    switch (TrackState)
    {
        case SCOPE_IDLE:
            CurrentRA += (TrackRateN[AXIS_RA].value / 3600.0 * dt) / 15.0;
            CurrentRA = range24(CurrentRA);
            break;

        case SCOPE_TRACKING:
            break;

        case SCOPE_SLEWING:
        case SCOPE_PARKING:
            /* slewing - nail it when both within one pulse @ SLEWRATE */
            nlocked = 0;

            dx = TargetRA - CurrentRA;

            // Take shortest path
            if (fabs(dx) > 12)
                dx *= -1;

            if (fabs(dx) <= da)
            {
                CurrentRA = TargetRA;
                nlocked++;
            }
            else if (dx > 0)
                CurrentRA += da / 15.;
            else
                CurrentRA -= da / 15.;

            if (CurrentRA < 0)
                CurrentRA += 24;
            else if (CurrentRA > 24)
                CurrentRA -= 24;

            dx = TargetDE - CurrentDE;
            if (fabs(dx) <= da)
            {
                CurrentDE = TargetDE;
                nlocked++;
            }
            else if (dx > 0)
                CurrentDE += da;
            else
                CurrentDE -= da;

            if (nlocked == 2)
            {
                if (TrackState == SCOPE_SLEWING)
                    TrackState = SCOPE_TRACKING;
                else
                    TrackState = SCOPE_PARKED;
            }

            break;

        default:
            break;
    }

    NewRaDec(CurrentRA, CurrentDE);
}
Esempio n. 3
0
double get_local_sidereal_time(double longitude)
{
    double SD = ln_get_apparent_sidereal_time(ln_get_julian_from_sys()) - (360.0 - longitude) / 15.0;

    return range24(SD);
}