Esempio n. 1
0
bool SynscanDriver::Goto(double ra, double dec)
{
    char cmd[SYN_RES] = {0}, res[SYN_RES] = {0};

    TargetRA = ra;
    TargetDE = dec;

    if (isSimulation())
        return true;

    // INDI is JNow. Synscan Controll uses J2000 Epoch
    ln_equ_posn epochPos { 0, 0 }, J2000Pos { 0, 0 };

    epochPos.ra  = ra * 15.0;
    epochPos.dec = dec;

    // For Alt/Az mounts, we must issue Goto Alt/Az
    if (m_isAltAz)
    {
        struct ln_lnlat_posn lnobserver;
        struct ln_hrz_posn lnaltaz;

        lnobserver.lng = LocationN[LOCATION_LONGITUDE].value;
        if (lnobserver.lng > 180)
            lnobserver.lng -= 360;
        lnobserver.lat = LocationN[LOCATION_LATITUDE].value;
        ln_get_hrz_from_equ(&epochPos, &lnobserver, ln_get_julian_from_sys(), &lnaltaz);
        /* libnova measures azimuth from south towards west */
        double az = range360(lnaltaz.az + 180);
        double al = lnaltaz.alt;

        return GotoAzAlt(az, al);
    }

    // Synscan accepts J2000 coordinates so we need to convert from JNow to J2000
    ln_get_equ_prec2(&epochPos, ln_get_julian_from_sys(), JD2000, &J2000Pos);

    // Mount deals in J2000 coords.
    uint32_t n1 = J2000Pos.ra  / 360  * 0x100000000;
    uint32_t n2 = J2000Pos.dec / 360 * 0x100000000;

    LOGF_DEBUG("Goto - JNow RA: %g JNow DE: %g J2000 RA: %g J2000 DE: %g", ra, dec, J2000Pos.ra / 15.0, J2000Pos.dec);


    snprintf(cmd, SYN_RES, "r%08X,%08X", n1, n2);
    if (sendCommand(cmd, res, 18))
    {
        TrackState = SCOPE_SLEWING;
        HorizontalCoordsNP.s = IPS_BUSY;
        IDSetNumber(&HorizontalCoordsNP, nullptr);
        return true;
    }

    return false;
}
Esempio n. 2
0
bool ScopeSim::Goto(double r, double d)
{
    targetRA  = r;
    targetDEC = d;
    char RAStr[64], DecStr[64];

    fs_sexa(RAStr, targetRA, 2, 3600);
    fs_sexa(DecStr, targetDEC, 2, 3600);

    ln_equ_posn lnradec { 0, 0 };

    lnradec.ra  = (currentRA * 360) / 24.0;
    lnradec.dec = currentDEC;

    ln_get_hrz_from_equ(&lnradec, &lnobserver, ln_get_julian_from_sys(), &lnaltaz);
    /* libnova measures azimuth from south towards west */
    double current_az = range360(lnaltaz.az + 180);
    //double current_alt =lnaltaz.alt;

    if (current_az > MIN_AZ_FLIP && current_az < MAX_AZ_FLIP)
    {
        lnradec.ra  = (r * 360) / 24.0;
        lnradec.dec = d;

        ln_get_hrz_from_equ(&lnradec, &lnobserver, ln_get_julian_from_sys(), &lnaltaz);

        double target_az = range360(lnaltaz.az + 180);

        //if (targetAz > currentAz && target_az > MIN_AZ_FLIP && target_az < MAX_AZ_FLIP)
        if (target_az >= current_az && target_az > MIN_AZ_FLIP)
        {
            forceMeridianFlip = true;
        }
    }

    TrackState = SCOPE_SLEWING;

    EqNP.s = IPS_BUSY;

    DEBUGF(INDI::Logger::DBG_SESSION, "Slewing to RA: %s - DEC: %s", RAStr, DecStr);
    return true;
}
Esempio n. 3
0
double ScopeSim::getAzimuth(double r, double d)
{
    ln_equ_posn lnradec { 0, 0 };
    ln_hrz_posn altaz { 0, 0 };

    lnradec.ra  = (r * 360) / 24.0;
    lnradec.dec = d;

    ln_get_hrz_from_equ(&lnradec, &lnobserver, ln_get_julian_from_sys(), &altaz);

    /* libnova measures azimuth from south towards west */
    return (range360(altaz.az + 180));
}
Esempio n. 4
0
bool SynscanDriver::ReadScopeStatus()
{
    if (isSimulation())
    {
        mountSim();
        return true;
    }

    char res[SYN_RES] = {0};

    // Goto in progress?
    if (sendCommand("L", res))
        m_MountInfo[MI_GOTO_STATUS] = res[0];

    // Pier side
    if (m_isAltAz == false && sendCommand("p", res))
    {
        m_MountInfo[MI_POINT_STATUS] = res[0];
        // INDI and mount pier sides are opposite to each other
        setPierSide(res[0] == 'W' ? PIER_EAST : PIER_WEST);
    }

    if (readTracking())
    {
        if (TrackState == SCOPE_SLEWING)
        {
            if (isSlewComplete())
            {
                TrackState = (m_TrackingFlag == 2) ? SCOPE_TRACKING : SCOPE_IDLE;
                HorizontalCoordsNP.s = (m_TrackingFlag == 2) ? IPS_OK : IPS_IDLE;
                IDSetNumber(&HorizontalCoordsNP, nullptr);
            }
        }
        else if (TrackState == SCOPE_PARKING)
        {
            if (isSlewComplete())
            {
                HorizontalCoordsNP.s = IPS_IDLE;
                IDSetNumber(&HorizontalCoordsNP, nullptr);
                TrackState = SCOPE_PARKED;
                SetTrackEnabled(false);
                SetParked(true);
            }
        }
        else if (TrackState == SCOPE_IDLE && m_TrackingFlag > 0)
            TrackState = SCOPE_TRACKING;
        else if (TrackState == SCOPE_TRACKING && m_TrackingFlag == 0)
            TrackState = SCOPE_IDLE;
    }

    sendStatus();

    // Get Precise RA/DE
    memset(res, 0, SYN_RES);
    if (!sendCommand("e", res))
        return false;

    uint32_t n1 = 0, n2 = 0;
    sscanf(res, "%x,%x#", &n1, &n2);
    double ra  = static_cast<double>(n1) / 0x100000000 * 360.0;
    double de  = static_cast<double>(n2) / 0x100000000 * 360.0;

    ln_equ_posn epochPos { 0, 0 }, J2000Pos { 0, 0 };
    J2000Pos.ra  = range360(ra);
    J2000Pos.dec = rangeDec(de);

    // Synscan reports J2000 coordinates so we need to convert from J2000 to JNow
    ln_get_equ_prec2(&J2000Pos, JD2000, ln_get_julian_from_sys(), &epochPos);

    CurrentRA = epochPos.ra / 15.0;
    CurrentDE = epochPos.dec;

    char Axis1Coords[MAXINDINAME] = {0}, Axis2Coords[MAXINDINAME] = {0};
    fs_sexa(Axis1Coords, J2000Pos.ra / 15.0, 2, 3600);
    fs_sexa(Axis2Coords, J2000Pos.dec, 2, 3600);
    LOGF_DEBUG("J2000 RA <%s> DE <%s>", Axis1Coords, Axis2Coords);
    memset(Axis1Coords, 0, MAXINDINAME);
    memset(Axis2Coords, 0, MAXINDINAME);
    fs_sexa(Axis1Coords, CurrentRA, 2, 3600);
    fs_sexa(Axis2Coords, CurrentDE, 2, 3600);
    LOGF_DEBUG("JNOW  RA <%s> DE <%s>", Axis1Coords, Axis2Coords);

    //  Now feed the rest of the system with corrected data
    NewRaDec(CurrentRA, CurrentDE);

    // Get precise az/alt
    memset(res, 0, SYN_RES);
    if (!sendCommand("z", res))
        return false;

    sscanf(res, "%x,%x#", &n1, &n2);
    double az  = static_cast<double>(n1) / 0x100000000 * 360.0;
    double al  = static_cast<double>(n2) / 0x100000000 * 360.0;
    al = rangeDec(al);

    HorizontalCoordsN[AXIS_AZ].value = az;
    HorizontalCoordsN[AXIS_ALT].value = al;

    memset(Axis1Coords, 0, MAXINDINAME);
    memset(Axis2Coords, 0, MAXINDINAME);
    fs_sexa(Axis1Coords, az, 2, 3600);
    fs_sexa(Axis2Coords, al, 2, 3600);
    LOGF_DEBUG("AZ <%s> ALT <%s>", Axis1Coords, Axis2Coords);

    IDSetNumber(&HorizontalCoordsNP, nullptr);

    return true;
}
Esempio n. 5
0
void DomeScript::TimerHit()
{
    if (!isConnected())
        return;
    char name[1024]={0};
    // N.B. INDI_UNUSED to make it compile on MacOS
    // DO NOT CHANGE
    char *s = tmpnam(name);
    INDI_UNUSED(s);
    bool status = RunScript(SCRIPT_STATUS, name, nullptr);
    if (status)
    {
        int parked = 0, shutter = 0;
        float az   = 0;
        FILE *file = fopen(name, "r");
        int ret    = 0;

        ret = fscanf(file, "%d %d %f", &parked, &shutter, &az);
        fclose(file);
        unlink(name);
        DomeAbsPosN[0].value = az = round(range360(az) * 10) / 10;
        if (parked != 0)
        {
            if (getDomeState() == DOME_PARKING || getDomeState() == DOME_UNPARKED)
            {
                SetParked(true);
                TargetAz = az;
                LOG_INFO("Park succesfully executed");
            }
        }
        else
        {
            if (getDomeState() == DOME_UNPARKING || getDomeState() == DOME_PARKED)
            {
                SetParked(false);
                TargetAz = az;
                LOG_INFO("Unpark succesfully executed");
            }
        }
        if (std::round(az * 10) != std::round(TargetAz * 10))
        {
            LOGF_INFO("Moving %g -> %g %d", std::round(az * 10) / 10,
                   std::round(TargetAz * 10) / 10, getDomeState());
            IDSetNumber(&DomeAbsPosNP, nullptr);
        }
        else if (getDomeState() == DOME_MOVING)
        {
            setDomeState(DOME_SYNCED);
            IDSetNumber(&DomeAbsPosNP, nullptr);
        }
        if (shutterState == SHUTTER_OPENED)
        {
            if (shutter == 0)
            {
                shutterState    = SHUTTER_CLOSED;
                DomeShutterSP.s = IPS_OK;
                IDSetSwitch(&DomeShutterSP, nullptr);
                LOG_INFO("Shutter was succesfully closed");
            }
        }
        else
        {
            if (shutter == 1)
            {
                shutterState    = SHUTTER_OPENED;
                DomeShutterSP.s = IPS_OK;
                IDSetSwitch(&DomeShutterSP, nullptr);
                LOG_INFO("Shutter was succesfully opened");
            }
        }
    }
    else
    {
        LOG_ERROR("Failed to read status");
    }
    SetTimer(POLLMS);
    if (!isParked() && TimeSinceUpdate++ > 4)
    {
        TimeSinceUpdate = 0;
        UpdateMountCoords();
    }
}
Esempio n. 6
0
void DomeSim::TimerHit()
{
    int nexttimer=1000;

    if(isConnected() == false) return;  //  No need to reset timer if we are not connected anymore    

    if (DomeAbsPosNP.s == IPS_BUSY)
    {
        if (targetAz > DomeAbsPosN[0].value)
        {
            DomeAbsPosN[0].value += DOME_SPEED;
        }
        else if (targetAz < DomeAbsPosN[0].value)
        {
            DomeAbsPosN[0].value -= DOME_SPEED;
        }

        DomeAbsPosN[0].value = range360(DomeAbsPosN[0].value);

        if (fabs(targetAz - DomeAbsPosN[0].value) <= DOME_SPEED)
        {
            DomeAbsPosN[0].value = targetAz;
            DEBUG(INDI::Logger::DBG_SESSION, "Dome reached requested azimuth angle.");

            if (getDomeState() == DOME_PARKING)
                SetParked(true);
            else if (getDomeState() == DOME_UNPARKING)
                SetParked(false);
            else
                setDomeState(DOME_SYNCED);
        }

        IDSetNumber(&DomeAbsPosNP, NULL);
    }

    if (DomeShutterSP.s == IPS_BUSY)
    {
        if (shutterTimer-- <= 0)
        {
            shutterTimer=0;
            DomeShutterSP.s = IPS_OK;
            DEBUGF(INDI::Logger::DBG_SESSION, "Shutter is %s.", (DomeShutterS[0].s == ISS_ON ? "open" : "closed"));
            IDSetSwitch(&DomeShutterSP, NULL);

            if (getDomeState() == DOME_UNPARKING)
                SetParked(false);
        }
    }
    SetTimer(nexttimer);
    //  Not all mounts update ra/dec constantly if tracking co-ordinates
    //  This is to ensure our alt/az gets updated even if ra/dec isn't being updated
    //  Once every 10 seconds is more than sufficient
    //  with this added, dome simulator will now correctly track telescope simulator
    //  which does not emit new ra/dec co-ords if they are not changing
    if(isParked() == false && TimeSinceUpdate++ > 9)
    {
        TimeSinceUpdate=0;
        UpdateMountCoords();
    }
    return;
}