Exemplo n.º 1
0
bool Camera_QHY::Disconnect()
{
    CancelQHYCCDExposingAndReadout(m_camhandle);  // for single frame mode use this to stop
    CloseQHYCCD(m_camhandle);
    m_camhandle = 0;
    Connected = false;
    delete[] RawBuffer;
    RawBuffer = 0;
    return false;
}
Exemplo n.º 2
0
bool QHYCCD::AbortExposure()
{
    int ret;

    if (!InExposure || sim)
    {
        InExposure = false;
        return true;
    }

    ret = CancelQHYCCDExposingAndReadout(camhandle);
    if (ret == QHYCCD_SUCCESS)
    {
        //AbortPrimaryFrame = true;
        InExposure = false;
        DEBUG(INDI::Logger::DBG_SESSION, "Exposure aborted.");
        return true;
    }
    else
        DEBUGF(INDI::Logger::DBG_ERROR, "Abort exposure failed (%d)", ret);

    return false;
}
Exemplo n.º 3
0
bool Camera_QHY::Capture(int duration, usImage& img, int options, const wxRect& subframe)
{
    bool useSubframe = UseSubframes && !subframe.IsEmpty();

    if (Binning != m_curBin)
    {
        FullSize = wxSize(m_maxSize.GetX() / Binning, m_maxSize.GetY() / Binning);
        m_curBin = Binning;
        useSubframe = false; // subframe may be out of bounds now
    }

    if (img.Init(FullSize))
    {
        DisconnectWithAlert(CAPT_FAIL_MEMORY);
        return true;
    }

    wxRect frame = useSubframe ? subframe : wxRect(FullSize);
    if (useSubframe)
        img.Clear();

    wxRect roi;

    if (useSubframe)
    {
        // Use a larger ROI around the subframe to avoid changing the ROI as the centroid
        // wobbles around. Changing the ROI introduces a lag of several seconds.
        // This also satifies the constraint that ROI width and height must be multiples of 4.
        enum { PAD = 1 << 5 };
        roi.SetLeft(round_down(subframe.GetLeft(), PAD));
        roi.SetRight(round_up(subframe.GetRight() + 1, PAD) - 1);
        roi.SetTop(round_down(subframe.GetTop(), PAD));
        roi.SetBottom(round_up(subframe.GetBottom() + 1, PAD) - 1);
    }
    else
    {
        roi = frame;
    }

    uint32_t ret = QHYCCD_ERROR;
    // lzr from QHY says this needs to be set for every exposure
    ret = SetQHYCCDBinMode(m_camhandle, Binning, Binning);
    if (ret != QHYCCD_SUCCESS)
    {
        Debug.Write(wxString::Format("SetQHYCCDBinMode failed! ret = %d\n", (int)ret));
    }

    if (m_roi != roi)
    {
        // when roi changes, must call this
        ret = CancelQHYCCDExposingAndReadout(m_camhandle);
        if (ret == QHYCCD_SUCCESS)
        {
            Debug.Write("CancelQHYCCDExposingAndReadout success\n");
        }
        else
        {
            Debug.Write("CancelQHYCCDExposingAndReadout failed\n");
        }

        ret = SetQHYCCDResolution(m_camhandle, roi.GetLeft(), roi.GetTop(), roi.GetWidth(), roi.GetHeight());
        if (ret == QHYCCD_SUCCESS)
        {
            m_roi = roi;
        }
        else
        {
            Debug.Write(wxString::Format("SetQHYCCDResolution(%d,%d,%d,%d) failed! ret = %d\n",
                roi.GetLeft(), roi.GetTop(), roi.GetWidth(), roi.GetHeight(), (int)ret));
        }
    }

    if (duration != m_curExposure)
    {
        ret = SetQHYCCDParam(m_camhandle, CONTROL_EXPOSURE, duration * 1000.0); // QHY duration is usec
        if (ret == QHYCCD_SUCCESS)
        {
            m_curExposure = duration;
        } 
        else
        {
            Debug.Write(wxString::Format("QHY set exposure ret %d\n", (int)ret));
            pFrame->Alert(_("Failed to set camera exposure"));
        }
    }

    if (GuideCameraGain != m_curGain)
    {
        double gain = m_gainMin + GuideCameraGain * (m_gainMax - m_gainMin) / 100.0;
        gain = floor(gain / m_gainStep) * m_gainStep;
        Debug.Write(wxString::Format("QHY set gain %g (%g..%g incr %g)\n", gain, m_gainMin, m_gainMax, m_gainStep));
        ret = SetQHYCCDParam(m_camhandle, CONTROL_GAIN, gain);
        if (ret == QHYCCD_SUCCESS)
        {
            m_curGain = GuideCameraGain;
        }
        else
        {
            Debug.Write(wxString::Format("QHY set gain ret %d\n", (int)ret));
            pFrame->Alert(_("Failed to set camera gain"));
        }
    }

    ret = ExpQHYCCDSingleFrame(m_camhandle);
    if (ret == QHYCCD_ERROR)
    {
        Debug.Write(wxString::Format("QHY exp single frame ret %d\n", (int)ret));
        DisconnectWithAlert(_("QHY exposure failed"), NO_RECONNECT);
        return true;
    }
    if (ret == QHYCCD_SUCCESS)
    {
        Debug.Write(wxString::Format("QHY: 200ms delay needed\n"));
        WorkerThread::MilliSleep(200);
    }
    if (ret == QHYCCD_READ_DIRECTLY)
    {
        //Debug.Write("QHYCCD_READ_DIRECTLY\n");
    }

    uint32_t w, h, bpp, channels;
    ret = GetQHYCCDSingleFrame(m_camhandle, &w, &h, &bpp, &channels, RawBuffer);
    if (ret != QHYCCD_SUCCESS || (bpp != 8 && bpp != 16))
    {
        Debug.Write(wxString::Format("QHY get single frame ret %d bpp %u\n", ret, bpp));
        // users report that reconnecting the camera after this failure allows
        // them to resume guiding so we'll try to reconnect automatically
        DisconnectWithAlert(_("QHY get frame failed"), RECONNECT);
        return true;
    }

    if (useSubframe)
    {
        img.Subframe = frame;

        int xofs = subframe.GetLeft() - roi.GetLeft();
        int yofs = subframe.GetTop() - roi.GetTop();

        int dxr = w - frame.width - xofs;
        if (bpp == 8)
        {
            const unsigned char *src = RawBuffer + yofs * w;
            unsigned short *dst = img.ImageData + frame.GetTop() * FullSize.GetWidth() + frame.GetLeft();
            for (int y = 0; y < frame.height; y++)
            {
                unsigned short *d = dst;
                src += xofs;
                for (int x = 0; x < frame.width; x++)
                    *d++ = (unsigned short) *src++;
                src += dxr;
                dst += FullSize.GetWidth();
            }
        }
        else // bpp == 16
        {
            const unsigned short *src = (const unsigned short *) RawBuffer + yofs * w;
            unsigned short *dst = img.ImageData + frame.GetTop() * FullSize.GetWidth() + frame.GetLeft();
            for (int y = 0; y < frame.height; y++)
            {
                src += xofs;
                memcpy(dst, src, frame.width * sizeof(unsigned short));
                src += frame.width + dxr;
                dst += FullSize.GetWidth();
            }
        }
    }
    else
    {
        if (bpp == 8)
        {
            const unsigned char *src = RawBuffer;
            unsigned short *dst = img.ImageData;
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    *dst++ = (unsigned short) *src++;
                }
            }
        }
        else // bpp == 16
        {
            memcpy(img.ImageData, RawBuffer, w * h * sizeof(unsigned short));
        }
    }

    if (options & CAPTURE_SUBTRACT_DARK)
        SubtractDark(img);
    if (Color && Binning == 1 && (options & CAPTURE_RECON))
        QuickLRecon(img);

    return false;
}