Exemple #1
0
bool NFocus::initProperties()
{
    INDI::Focuser::initProperties();

    // No speed for nfocus
    FocusSpeedN[0].min = FocusSpeedN[0].max = FocusSpeedN[0].value = 1;

    IUUpdateMinMax(&FocusSpeedNP);

    /* Focuser temperature */
    IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", 0, 65000., 0., 10000.);
    IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature",
                       MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);

    /* Settings of the Nfocus */
    IUFillNumber(&SettingsN[0], "ON time", "ON waiting time", "%6.0f", 10., 250., 0., 73.);
    IUFillNumber(&SettingsN[1], "OFF time", "OFF waiting time", "%6.0f", 1., 250., 0., 15.);
    IUFillNumber(&SettingsN[2], "Fast Mode Delay", "Fast Mode Delay", "%6.0f", 0., 255., 0., 9.);
    IUFillNumberVector(&SettingsNP, SettingsN, 3, getDeviceName(), "FOCUS_SETTINGS", "Settings", OPTIONS_TAB, IP_RW, 0,
                       IPS_IDLE);

    /* tick scaling factor. Inward dir ticks times this factor is considered to
    be the same as outward dir tick numbers. This is to compensate  for DC motor
    incapabilities with regards to exact positioning at least a bit on the mass
    dependent path.... */
    IUFillNumber(&InOutScalarN[0], "In/Out Scalar", "In/Out Scalar", "%1.2f", 0., 2., 1., 1.0);
    IUFillNumberVector(&InOutScalarNP, InOutScalarN, 1, getDeviceName(), "FOCUS_DIRSCALAR", "Direction scaling factor",
                       OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    /* Nfocus should stay within these limits */
    IUFillNumber(&MinMaxPositionN[0], "MINPOS", "Minimum Tick", "%6.0f", -65000., 65000., 0., -65000.);
    IUFillNumber(&MinMaxPositionN[1], "MAXPOS", "Maximum Tick", "%6.0f", 1., 65000., 0., 65000.);
    IUFillNumberVector(&MinMaxPositionNP, MinMaxPositionN, 2, getDeviceName(), "FOCUS_MINMAXPOSITION", "Extrema",
                       OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    IUFillNumber(&MaxTravelN[0], "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 64000., 0., 10000.);
    IUFillNumberVector(&MaxTravelNP, MaxTravelN, 1, getDeviceName(), "FOCUS_MAXTRAVEL", "Max. travel", OPTIONS_TAB,
                       IP_RW, 0, IPS_IDLE);

    /* Set Nfocus position register to this position */
    IUFillNumber(&SyncN[0], "FOCUS_SYNC_OFFSET", "Offset", "%.f", 0, 64000., 0., 0.);
    IUFillNumberVector(&SyncNP, SyncN, 1, getDeviceName(), "FOCUS_SYNC", "Sync", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);

    /* Relative and absolute movement */
    FocusRelPosN[0].min   = 0;
    FocusRelPosN[0].max   = MinMaxPositionN[1].value;
    FocusRelPosN[0].value = 1000;
    FocusRelPosN[0].step  = 100;

    FocusAbsPosN[0].min   = MinMaxPositionN[0].min;
    FocusAbsPosN[0].max   = MinMaxPositionN[0].max;
    FocusAbsPosN[0].value = 0;
    FocusAbsPosN[0].step  = 10000;

    addAuxControls();

    return true;
}
Exemple #2
0
void CCDChip::setResolutoin(int x, int y)
{
    XRes = x;
    YRes = y;

    ImagePixelSizeN[0].value=x;
    ImagePixelSizeN[1].value=y;

    IDSetNumber(ImagePixelSizeNP, NULL);

    ImageFrameN[FRAME_W].max = x;
    ImageFrameN[FRAME_H].max = y;
    IUUpdateMinMax(ImageFrameNP);
}
Exemple #3
0
bool NStep::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
{
    if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
    {
        // Compensation Settings
        if (!strcmp(name, CompensationSettingsNP.name))
        {
            // Extract values
            int change = 0, step = 0, backlash = 0, timer = 0;
            for (int i = 0; i < n; i++)
            {
                if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_CHANGE].name))
                {
                    change = values[i];
                }
                else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_STEP].name))
                {
                    step = values[i];
                }
                else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_BACKLASH].name))
                {
                    backlash = values[i];
                }
                else if (!strcmp(names[i], CompensationSettingsN[COMPENSATION_SETTING_TIMER].name))
                {
                    timer = values[i];
                }
            }

            // Try to update settings
            if (setCompensationSettings(change, step, backlash, timer))
            {
                IUUpdateNumber(&CompensationSettingsNP, values, names, n);
                CompensationSettingsNP.s = IPS_OK;
            }
            else
            {
                CompensationSettingsNP.s = IPS_ALERT;
            }

            IDSetNumber(&CompensationSettingsNP, nullptr);
            return true;
        }


        // Stepping Phase
        if (!strcmp(name, SteppingPhaseNP.name))
        {
            if (setSteppingPhase(static_cast<uint8_t>(values[0])))
            {
                IUUpdateNumber(&SteppingPhaseNP, values, names, n);
                SteppingPhaseNP.s = IPS_OK;
            }
            else
                SteppingPhaseNP.s = IPS_ALERT;

            IDSetNumber(&SteppingPhaseNP, nullptr);
            return true;
        }

        // Max Speed
        if (!strcmp(name, MaxSpeedNP.name))
        {
            if (setMaxSpeed(static_cast<uint8_t>(values[0])))
            {
                IUUpdateNumber(&MaxSpeedNP, values, names, n);
                MaxSpeedNP.s = IPS_OK;

                // We must update the Min/Max of focus speed
                FocusSpeedN[0].max = values[0];
                IUUpdateMinMax(&FocusSpeedNP);
            }
            else
            {
                MaxSpeedNP.s = IPS_ALERT;
            }

            IDSetNumber(&MaxSpeedNP, nullptr);
            return true;
        }
    }

    return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
}
Exemple #4
0
bool QSICCD::setupParams()
{
    string name,model;
    double temperature;
    double pixel_size_x,pixel_size_y;
    long sub_frame_x,sub_frame_y;
    try
    {
        QSICam.get_Name(name);
        QSICam.get_ModelNumber(model);
        QSICam.get_PixelSizeX(&pixel_size_x);
        QSICam.get_PixelSizeY(&pixel_size_y);
        QSICam.get_NumX(&sub_frame_x);
        QSICam.get_NumY(&sub_frame_y);
        QSICam.get_CCDTemperature(&temperature);
    } catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_ERROR, "Setup Params failed. %s.", err.what());
        return false;
    }

    DEBUGF(INDI::Logger::DBG_SESSION, "The CCD Temperature is %f.", temperature);

    TemperatureN[0].value = temperature;			/* CCD chip temperatre (degrees C) */
    IDSetNumber(&TemperatureNP, NULL);

    SetCCDParams(sub_frame_x, sub_frame_y, 16, pixel_size_x, pixel_size_y);

    imageWidth  = PrimaryCCD.getSubW();
    imageHeight = PrimaryCCD.getSubH();

    int nbuf;
    nbuf=PrimaryCCD.getXRes()*PrimaryCCD.getYRes() * PrimaryCCD.getBPP()/8;                 //  this is pixel count
    nbuf+=512;                      //  leave a little extra at the end
    PrimaryCCD.setFrameBufferSize(nbuf);

    try
    {
     QSICam.get_Name(name);
    } catch (std::runtime_error& err)
    {
        DEBUGF(INDI::Logger::DBG_ERROR, "get_Name() failed. %s.", err.what());
        return false;
    }
    DEBUGF(INDI::Logger::DBG_SESSION, "%s", name.c_str());

    int filter_count;
    try
    {
            QSICam.get_FilterCount(filter_count);
    } catch (std::runtime_error err)
    {
            DEBUGF(INDI::Logger::DBG_SESSION, "get_FilterCount() failed. %s.", err.what());
            return false;
    }

    DEBUGF(INDI::Logger::DBG_SESSION,"The filter count is %d", filter_count);


    FilterSlotN[0].max = filter_count;
    FilterSlotNP.s = IPS_OK;

    IUUpdateMinMax(&FilterSlotNP);
    IDSetNumber(&FilterSlotNP, NULL);

    FilterSP.s = IPS_OK;
    IDSetSwitch(&FilterSP,NULL);

    GetFilterNames(FILTER_TAB);

    double minDuration=0;

    try
    {
        QSICam.get_MinExposureTime(&minDuration);
    } catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_ERROR, "get_MinExposureTime() failed. %s.", err.what());
        return false;
    }

    PrimaryCCD.setMinMaxStep("CCD_EXPOSURE", "CCD_EXPOSURE_VALUE", minDuration, 3600, 1, true);

    bool coolerOn=false;

    try
    {
         QSICam.get_CoolerOn(&coolerOn);
    } catch (std::runtime_error err)
    {
            CoolerSP.s = IPS_IDLE;
            CoolerS[0].s = ISS_OFF;
            CoolerS[1].s = ISS_ON;
            DEBUGF(INDI::Logger::DBG_ERROR, "Error: CoolerOn() failed. %s.", err.what());
            IDSetSwitch(&CoolerSP, NULL);
            return false;
    }

    CoolerS[0].s = coolerOn ? ISS_ON : ISS_OFF;
    CoolerS[1].s = coolerOn ? ISS_OFF : ISS_ON;
    CoolerSP.s = IPS_OK;
    IDSetSwitch(&CoolerSP, NULL);

    QSICamera::CameraGain cGain = QSICamera::CameraGainAuto;
    canSetGain = false;

    QSICam.get_CanSetGain(&canSetGain);

    if (canSetGain)
    {
        try
        {
            QSICam.get_CameraGain(&cGain);
        }
        catch (std::runtime_error err)
        {
            DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support gain. %s.", err.what());
            canSetGain = false;
        }

        if (canSetGain)
        {
            IUResetSwitch(&GainSP);
            GainS[cGain].s = ISS_ON;
            defineSwitch(&GainSP);
        }
    }

    QSICamera::AntiBloom cAB = QSICamera::AntiBloomNormal;
    canSetAB = true;

    try
    {
        QSICam.get_AntiBlooming(&cAB);
    }
    catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support AntiBlooming control. %s.", err.what());
        canSetAB = false;
    }

    if (canSetAB)
    {
        IUResetSwitch(&ABSP);
        ABS[cAB].s = ISS_ON;
        defineSwitch(&ABSP);
    }


    QSICamera::FanMode fMode = QSICamera::fanOff;
    canControlFan = true;

    try
    {
        QSICam.get_FanMode(fMode);
    }
    catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support fan control. %s.", err.what());
        canControlFan = false;
    }

    if (canControlFan)
    {
        IUResetSwitch(&FanSP);
        FanS[fMode].s = ISS_ON;
        defineSwitch(&FanSP);
    }

    canChangeReadoutSpeed = true;
    QSICamera::ReadoutSpeed cReadoutSpeed;

    try
    {
        QSICam.get_ReadoutSpeed(cReadoutSpeed);
    }
    catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what());
        canChangeReadoutSpeed = false;
    }

    if (canChangeReadoutSpeed)
    {
        // get_ReadoutSpeed succeeds even if the camera does not support that, so the only way to make sure is to set it
        try
        {
            QSICam.put_ReadoutSpeed(cReadoutSpeed);
        }
        catch (std::runtime_error err)
        {
            DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not support changing readout speed. %s.", err.what());
            canChangeReadoutSpeed = false;
        }

        if (canChangeReadoutSpeed)
        {
            IUResetSwitch(&ReadOutSP);
            ReadOutS[cReadoutSpeed].s = ISS_ON;
            defineSwitch(&ReadOutSP);
        }
    }

    // Can flush
    canFlush = false;
    try
    {
        QSICam.put_PreExposureFlush(QSICamera::FlushNormal);
        canFlush = true;
    }
    catch (std::runtime_error err)
    {
        DEBUGF(INDI::Logger::DBG_DEBUG, "Camera does not pre-exposure flushing %s.", err.what());
        canFlush = false;
    }

    return true;
}
Exemple #5
0
bool NFocus::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
{
    int nset = 0, i = 0;

    if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
    {
        if (strcmp(name, SettingsNP.name) == 0)
        {
            /* new speed */
            double new_onTime    = 0;
            double new_offTime   = 0;
            double new_fastDelay = 0;
            int ret              = -1;

            for (nset = i = 0; i < n; i++)
            {
                /* Find numbers with the passed names in the SettingsNP property */
                INumber *eqp = IUFindNumber(&SettingsNP, names[i]);

                /* If the number found is  (SettingsN[0]) then process it */
                if (eqp == &SettingsN[0])
                {
                    new_onTime = (values[i]);
                    nset += static_cast<int>(new_onTime >= 10 && new_onTime <= 250);
                }
                else if (eqp == &SettingsN[1])
                {
                    new_offTime = (values[i]);
                    nset += static_cast<int>(new_offTime >= 1 && new_offTime <= 250);
                }
                else if (eqp == &SettingsN[2])
                {
                    new_fastDelay = (values[i]);
                    nset += static_cast<int>(new_fastDelay >= 1 && new_fastDelay <= 9);
                }
            }

            /* Did we process the three numbers? */
            if (nset == 3)
            {
                if ((ret = updateNFMotorSettings(&new_onTime, &new_offTime, &new_fastDelay)) < 0)
                {
                    IDSetNumber(&SettingsNP, "Changing to new settings failed");
                    return false;
                }

                currentOnTime    = new_onTime;
                currentOffTime   = new_offTime;
                currentFastDelay = new_fastDelay;

                SettingsNP.s = IPS_OK;
                IDSetNumber(&SettingsNP, "Motor settings are now  %3.0f %3.0f %3.0f", currentOnTime, currentOffTime,
                            currentFastDelay);
                return true;
            }
            else
            {
                /* Set property state to idle */
                SettingsNP.s = IPS_IDLE;

                IDSetNumber(&SettingsNP, "Settings absent or bogus.");
                return false;
            }
        }

        if (strcmp(name, InOutScalarNP.name) == 0)
        {
            double new_ioscalar = 0;

            for (nset = i = 0; i < n; i++)
            {
                /* Find numbers with the passed names in the InOutScalarNP property */
                INumber *eqp = IUFindNumber(&InOutScalarNP, names[i]);

                /* If the number found is SetBacklash (SetBacklashN[0]) then process it */
                if (eqp == &InOutScalarN[0])
                {
                    new_ioscalar = (values[i]);

                    /* limits */
                    nset += static_cast<int>(new_ioscalar >= 0 && new_ioscalar <= 2);
                }

                if (nset == 1)
                {
                    /* Set the nfocus state to BUSY */
                    InOutScalarNP.s = IPS_BUSY;
                    /* kraemerf
                    IDSetNumber(&InOutScalarNP, nullptr);

                        if(( ret= updateNFInOutScalar(&new_ioscalar)) < 0) {

                          InOutScalarNP.s = IPS_IDLE;
                          IDSetNumber(&InOutScalarNP, "Setting new in/out scalar failed.");

                          return false ;
                        }
                    */

                    currentInOutScalar = new_ioscalar;
                    InOutScalarNP.s    = IPS_OK;
                    IDSetNumber(&InOutScalarNP, "Direction Scalar is now  %1.2f", currentInOutScalar);
                    return true;
                }
                else
                {
                    InOutScalarNP.s = IPS_IDLE;
                    IDSetNumber(&InOutScalarNP, "Need exactly one parameter.");

                    return false;
                }
            }
        }

        if (strcmp(name, MinMaxPositionNP.name) == 0)
        {
            /* new positions */
            double new_min = 0;
            double new_max = 0;

            for (nset = i = 0; i < n; i++)
            {
                /* Find numbers with the passed names in the MinMaxPositionNP property */
                INumber *mmpp = IUFindNumber(&MinMaxPositionNP, names[i]);

                /* If the number found is  (MinMaxPositionN[0]) then process it */
                if (mmpp == &MinMaxPositionN[0])
                {
                    new_min = (values[i]);
                    nset += static_cast<int>(new_min >= 1 && new_min <= 65000);
                }
                else if (mmpp == &MinMaxPositionN[1])
                {
                    new_max = (values[i]);
                    nset += static_cast<int>(new_max >= 1 && new_max <= 65000);
                }
            }

            /* Did we process the two numbers? */
            if (nset == 2)
            {
                /* Set the nfocus state to BUSY */
                MinMaxPositionNP.s = IPS_BUSY;

                currentMinPosition = new_min;
                currentMaxPosition = new_max;

                MinMaxPositionNP.s = IPS_OK;
                IDSetNumber(&MinMaxPositionNP, "Minimum and Maximum settings are now  %3.0f %3.0f", currentMinPosition,
                            currentMaxPosition);
                return true;
            }
            else
            {
                /* Set property state to idle */
                MinMaxPositionNP.s = IPS_IDLE;

                IDSetNumber(&MinMaxPositionNP, "Minimum and maximum limits absent or bogus.");

                return false;
            }
        }

        if (strcmp(name, MaxTravelNP.name) == 0)
        {
            double new_maxt = 0;
            int ret         = -1;

            for (nset = i = 0; i < n; i++)
            {
                /* Find numbers with the passed names in the MinMaxPositionNP property */
                INumber *mmpp = IUFindNumber(&MaxTravelNP, names[i]);

                /* If the number found is  (MaxTravelN[0]) then process it */
                if (mmpp == &MaxTravelN[0])
                {
                    new_maxt = (values[i]);
                    nset += static_cast<int>(new_maxt >= 1 && new_maxt <= 64000);
                }
            }
            /* Did we process the one number? */
            if (nset == 1)
            {
                IDSetNumber(&MinMaxPositionNP, nullptr);

                if ((ret = setNFMaxPosition(&new_maxt)) < 0)
                {
                    MaxTravelNP.s = IPS_IDLE;
                    IDSetNumber(&MaxTravelNP, "Changing to new maximum travel failed");
                    return false;
                }

                currentMaxTravel    = new_maxt;
                MaxTravelNP.s       = IPS_OK;
                FocusAbsPosN[0].max = currentMaxTravel;
                IUUpdateMinMax(&FocusAbsPosNP);
                IDSetNumber(&MaxTravelNP, "Maximum travel is now  %3.0f", currentMaxTravel);
                return true;
            }
            else
            {
                /* Set property state to idle */

                MaxTravelNP.s = IPS_IDLE;
                IDSetNumber(&MaxTravelNP, "Maximum travel absent or bogus.");

                return false;
            }
        }

        // Sync
        if (strcmp(name, SyncNP.name) == 0)
        {
            double new_apos = values[0];
            int rc          = 0;
            if ((new_apos < currentMinPosition) || (new_apos > currentMaxPosition))
            {
                SyncNP.s = IPS_ALERT;
                IDSetNumber(&SyncNP, "Value out of limits  %5.0f", new_apos);
                return false;
            }

            if ((rc = syncNF(&new_apos)) < 0)
            {
                SyncNP.s = IPS_ALERT;
                IDSetNumber(&SyncNP, "Read out of the set position to %3d failed.", rc);
                return false;
            }

            DEBUGF(INDI::Logger::DBG_DEBUG, "Focuser sycned to %g ticks", new_apos);
            SyncN[0].value = new_apos;
            SyncNP.s       = IPS_OK;
            IDSetNumber(&SyncNP, nullptr);
            IDSetNumber(&FocusAbsPosNP, nullptr);
            return true;
        }
    }

    return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
}
Exemple #6
0
bool FocuserInterface::processNumber(const char * dev, const char * name, double values[], char * names[], int n)
{
    // Move focuser based on requested timeout
    if (!strcmp(name, FocusTimerNP.name))
    {
        FocusDirection dir;
        int speed;
        int t;

        //  first we get all the numbers just sent to us
        IUUpdateNumber(&FocusTimerNP, values, names, n);

        //  Now lets find what we need for this move
        speed = FocusSpeedN[0].value;

        if (FocusMotionS[0].s == ISS_ON)
            dir = FOCUS_INWARD;
        else
            dir = FOCUS_OUTWARD;

        t              = FocusTimerN[0].value;
        lastTimerValue = t;

        FocusTimerNP.s = MoveFocuser(dir, speed, t);
        IDSetNumber(&FocusTimerNP, nullptr);
        return true;
    }

    // Set variable focus speed
    if (!strcmp(name, FocusSpeedNP.name))
    {
        FocusSpeedNP.s    = IPS_OK;
        int current_speed = FocusSpeedN[0].value;
        IUUpdateNumber(&FocusSpeedNP, values, names, n);

        if (SetFocuserSpeed(FocusSpeedN[0].value) == false)
        {
            FocusSpeedN[0].value = current_speed;
            FocusSpeedNP.s       = IPS_ALERT;
        }

        //  Update client display
        IDSetNumber(&FocusSpeedNP, nullptr);
        return true;
    }

    // Update Maximum Position allowed
    if (!strcmp(name, FocusMaxPosNP.name))
    {
        uint32_t maxTravel = rint(values[0]);
        if (SetFocuserMaxPosition(maxTravel))
        {
            IUUpdateNumber(&FocusMaxPosNP, values, names, n);

            FocusAbsPosN[0].max = FocusSyncN[0].max = FocusMaxPosN[0].value;
            FocusAbsPosN[0].step = FocusSyncN[0].step = FocusMaxPosN[0].value / 50.0;
            FocusAbsPosN[0].min = FocusSyncN[0].min = 0;

            FocusRelPosN[0].max  = FocusMaxPosN[0].value / 2;
            FocusRelPosN[0].step = FocusMaxPosN[0].value / 100.0;
            FocusRelPosN[0].min  = 0;

            IUUpdateMinMax(&FocusAbsPosNP);
            IUUpdateMinMax(&FocusRelPosNP);
            IUUpdateMinMax(&FocusSyncNP);

            FocusMaxPosNP.s = IPS_OK;
        }
        else
            FocusMaxPosNP.s = IPS_ALERT;

        IDSetNumber(&FocusMaxPosNP, nullptr);
        return true;
    }

    // Sync
    if (!strcmp(name, FocusSyncNP.name))
    {
        if (SyncFocuser(rint(values[0])))
        {
            FocusSyncN[0].value = FocusAbsPosN[0].value = rint(values[0]);
            FocusSyncNP.s = IPS_OK;
            IDSetNumber(&FocusSyncNP, nullptr);
            IDSetNumber(&FocusAbsPosNP, nullptr);
        }
        else
        {
            FocusSyncNP.s = IPS_ALERT;
            IDSetNumber(&FocusSyncNP, nullptr);
        }
        return true;
    }

    // Update Absolute Focuser Position
    if (!strcmp(name, FocusAbsPosNP.name))
    {
        int newPos = rint(values[0]);

        if (newPos < FocusAbsPosN[0].min)
        {
            FocusAbsPosNP.s = IPS_ALERT;
            IDSetNumber(&FocusAbsPosNP, nullptr);
            DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus minimum position is %g",
                         FocusAbsPosN[0].min);
            return false;
        }
        else if (newPos > FocusAbsPosN[0].max)
        {
            FocusAbsPosNP.s = IPS_ALERT;
            IDSetNumber(&FocusAbsPosNP, nullptr);
            DEBUGFDEVICE(dev, Logger::DBG_ERROR, "Requested position out of bound. Focus maximum position is %g",
                         FocusAbsPosN[0].max);
            return false;
        }

        IPState ret;

        if ((ret = MoveAbsFocuser(newPos)) == IPS_OK)
        {
            FocusAbsPosNP.s = IPS_OK;
            IUUpdateNumber(&FocusAbsPosNP, values, names, n);
            DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser moved to position %d", newPos);
            IDSetNumber(&FocusAbsPosNP, nullptr);
            return true;
        }
        else if (ret == IPS_BUSY)
        {
            FocusAbsPosNP.s = IPS_BUSY;
            DEBUGFDEVICE(dev, Logger::DBG_SESSION, "Focuser is moving to position %d", newPos);
            IDSetNumber(&FocusAbsPosNP, nullptr);
            return true;
        }

        FocusAbsPosNP.s = IPS_ALERT;
        DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position.");
        IDSetNumber(&FocusAbsPosNP, nullptr);
        return false;
    }

    // Update Relative focuser steps. This moves the focuser CW/CCW by this number of steps.
    if (!strcmp(name, FocusRelPosNP.name))
    {
        int newPos = rint(values[0]);

        if (newPos <= 0)
        {
            DEBUGDEVICE(dev, Logger::DBG_ERROR, "Relative ticks value must be greater than zero.");
            FocusRelPosNP.s = IPS_ALERT;
            IDSetNumber(&FocusRelPosNP, nullptr);
            return false;
        }

        IPState ret;

        if (CanAbsMove())
        {
            if (FocusMotionS[0].s == ISS_ON)
            {
                if (FocusAbsPosN[0].value - newPos < FocusAbsPosN[0].min)
                {
                    FocusRelPosNP.s = IPS_ALERT;
                    IDSetNumber(&FocusRelPosNP, nullptr);
                    DEBUGFDEVICE(dev, Logger::DBG_ERROR,
                                 "Requested position out of bound. Focus minimum position is %g", FocusAbsPosN[0].min);
                    return false;
                }
            }
            else
            {
                if (FocusAbsPosN[0].value + newPos > FocusAbsPosN[0].max)
                {
                    FocusRelPosNP.s = IPS_ALERT;
                    IDSetNumber(&FocusRelPosNP, nullptr);
                    DEBUGFDEVICE(dev, Logger::DBG_ERROR,
                                 "Requested position out of bound. Focus maximum position is %g", FocusAbsPosN[0].max);
                    return false;
                }
            }
        }

        if ((ret = MoveRelFocuser((FocusMotionS[0].s == ISS_ON ? FOCUS_INWARD : FOCUS_OUTWARD), newPos)) == IPS_OK)
        {
            FocusRelPosNP.s = FocusAbsPosNP.s = IPS_OK;
            IUUpdateNumber(&FocusRelPosNP, values, names, n);
            IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps %s", newPos,
                        FocusMotionS[0].s == ISS_ON ? "inward" : "outward");
            IDSetNumber(&FocusAbsPosNP, nullptr);
            return true;
        }
        else if (ret == IPS_BUSY)
        {
            IUUpdateNumber(&FocusRelPosNP, values, names, n);
            FocusRelPosNP.s = FocusAbsPosNP.s = IPS_BUSY;
            IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps %s...", newPos,
                        FocusMotionS[0].s == ISS_ON ? "inward" : "outward");
            IDSetNumber(&FocusAbsPosNP, nullptr);
            return true;
        }

        FocusRelPosNP.s = IPS_ALERT;
        DEBUGDEVICE(dev, Logger::DBG_ERROR, "Focuser failed to move to new requested position.");
        IDSetNumber(&FocusRelPosNP, nullptr);
        return false;
    }

    return false;
}
Exemple #7
0
bool NFocus::initProperties()
{
    INDI::Focuser::initProperties();

    // No speed for nfocus
    FocusSpeedN[0].min = FocusSpeedN[0].max = FocusSpeedN[0].value = 1;

    IUUpdateMinMax(&FocusSpeedNP);

    /* Port */
    IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyACM0");
    IUFillTextVector(&PortTP, PortT, 1, getDeviceName(), "DEVICE_PORT", "Ports", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);


    /* Focuser temperature */
    IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", 0, 65000., 0., 10000.);
    IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);

    /* Timed move Settings */
    IUFillNumber(&FocusTimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%5.0f",0.0,10000.0,10.0,10000.0);
    IUFillNumberVector(&FocusTimerNP,FocusTimerN,1,getDeviceName(),"FOCUS_TIMER","Timer",MAIN_CONTROL_TAB,IP_RW,60,IPS_OK);

    /* Settings of the Nfocus */
    IUFillNumber(&SettingsN[0], "ON time", "ON waiting time", "%6.0f", 10., 250., 0., 73.);
    IUFillNumber(&SettingsN[1], "OFF time", "OFF waiting time", "%6.0f", 1., 250., 0., 15.);
    IUFillNumber(&SettingsN[2], "Fast Mode Delay", "Fast Mode Delay", "%6.0f", 0., 255., 0., 9.);
    IUFillNumberVector(&SettingsNP, SettingsN, 3, getDeviceName(), "FOCUS_SETTINGS", "Settings", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    /* tick scaling factor. Inward dir ticks times this factor is considered to 
    be the same as outward dir tick numbers. This is to compensate  for DC motor 
    incapabilities with regards to exact positioning at least a bit on the mass
    dependent path.... */
    IUFillNumber(&InOutScalarN[0], "In/Out Scalar", "In/Out Scalar", "%1.2f", 0., 2., 1., 1.0);
    IUFillNumberVector(&InOutScalarNP, InOutScalarN, 1, getDeviceName(), "FOCUS_DIRSCALAR", "Direction scaling factor", OPTIONS_TAB, IP_RW, 0, IPS_IDLE );

    /* Nfocus should stay within these limits */
    IUFillNumber(&MinMaxPositionN[0], "MINPOS", "Minimum Tick", "%6.0f", -65000., 65000., 0., -65000. );
    IUFillNumber(&MinMaxPositionN[1], "MAXPOS", "Maximum Tick", "%6.0f", 1., 65000., 0., 65000.);
    IUFillNumberVector(&MinMaxPositionNP, MinMaxPositionN, 2, getDeviceName(), "FOCUS_MINMAXPOSITION", "Extrema", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    IUFillNumber(&MaxTravelN[0], "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 64000., 0., 10000.);
    IUFillNumberVector(&MaxTravelNP, MaxTravelN, 1, getDeviceName(), "FOCUS_MAXTRAVEL", "Max. travel", OPTIONS_TAB, IP_RW, 0, IPS_IDLE );

    /* Set Nfocus position register to this position */
    IUFillNumber(&SetRegisterPositionN[0], "SETPOS", "Position", "%6.0f", 0, 64000., 0., 0. );
    IUFillNumberVector(&SetRegisterPositionNP, SetRegisterPositionN, 1, getDeviceName(), "FOCUS_REGISTERPOSITION", "Set register", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    /* Backlash */
    IUFillNumber(&SetBacklashN[0], "SETBACKLASH", "Backlash", "%6.0f", -255., 255., 0., 0.);
    IUFillNumberVector(&SetBacklashNP, SetBacklashN, 1, getDeviceName(), "FOCUS_BACKLASH", "Set Register", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);

    /* Relative and absolute movement */
    FocusRelPosN[0].min = -65000.;
    FocusRelPosN[0].max = 65000.;
    FocusRelPosN[0].value = 0;
    FocusRelPosN[0].step = 100;

    FocusAbsPosN[0].min = 0.;
    FocusAbsPosN[0].max = 65000.;
    FocusAbsPosN[0].value = 0;
    FocusAbsPosN[0].step = 10000;

    addDebugControl();

    return true;

}