Example #1
0
bool ScopeASCOM::GetCoordinates(double *ra, double *dec, double *siderealTime)
{
    bool bError = false;

    try
    {
        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: cannot get coordinates when not connected");
        }

        if (!m_bCanGetCoordinates)
        {
            throw THROW_INFO("ASCOM Scope: not capable of getting coordinates");
        }

        GITObjRef scope(m_gitEntry);

        Variant vRA;

        if (!scope.GetProp(&vRA, dispid_rightascension))
        {
            throw ERROR_INFO("ASCOM Scope: get right ascension failed: " + ExcepMsg(scope.Excep()));
        }

        Variant vDec;

        if (!scope.GetProp(&vDec, dispid_declination))
        {
            throw ERROR_INFO("ASCOM Scope: get declination failed: " + ExcepMsg(scope.Excep()));
        }

        Variant vST;

        if (!scope.GetProp(&vST, dispid_siderealtime))
        {
            throw ERROR_INFO("ASCOM Scope: get sidereal time failed: " + ExcepMsg(scope.Excep()));
        }

        *ra = vRA.dblVal;
        *dec = vDec.dblVal;
        *siderealTime = vST.dblVal;
    }
    catch (wxString Msg)
    {
        bError = true;
        POSSIBLY_UNUSED(Msg);
    }

    return bError;
}
Example #2
0
bool ScopeASCOM::IsGuiding(DispatchObj *scope)
{
    bool bReturn = true;

    try
    {
        if (!m_bCanCheckPulseGuiding)
        {
            // Assume all is good - best we can do as this is really a fail-safe check.  If we can't call this property (lame driver) guides will have to
            // enforce the wait.  But, enough don't support this that we can't throw an error.
            throw ERROR_INFO("ASCOM Scope: IsGuiding - !m_bCanCheckPulseGuiding");
        }

        // First, check to see if already moving
        Variant vRes;
        if (!scope->GetProp(&vRes, dispid_ispulseguiding))
        {
            pFrame->Alert(_("ASCOM driver failed checking IsPulseGuiding"));
            throw ERROR_INFO("ASCOM Scope: IsGuiding - IsPulseGuiding failed: " + ExcepMsg(scope->Excep()));
        }

        bReturn = vRes.boolVal == VARIANT_TRUE;
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
        bReturn = false;
    }

    Debug.AddLine("IsGuiding returns %d", bReturn);

    return bReturn;
}
Example #3
0
// Return RA and Dec guide rates in native ASCOM units, degrees/sec.
// Convention is to return true on an error
bool ScopeASCOM::GetGuideRates(double *pRAGuideRate, double *pDecGuideRate)
{
    bool bError = false;

    try
    {
        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: cannot get guide rates when not connected");
        }

        if (!m_bCanGetGuideRates)
        {
            throw THROW_INFO("ASCOM Scope: not capable of getting guide rates");
        }

        GITObjRef scope(m_gitEntry);

        Variant vRes;

        if (!scope.GetProp(&vRes, dispid_decguiderate))
        {
            throw ERROR_INFO("ASCOM Scope: GuideRateDec() failed: " + ExcepMsg(scope.Excep()));
        }

        *pDecGuideRate = vRes.dblVal;

        if (!scope.GetProp(&vRes, dispid_raguiderate))
        {
            throw ERROR_INFO("ASCOM Scope: GuideRateRA() failed: " + ExcepMsg(scope.Excep()));
        }

        *pRAGuideRate = vRes.dblVal;
    }
    catch (wxString Msg)
    {
        bError = true;
        POSSIBLY_UNUSED(Msg);
    }

    Debug.AddLine("ScopeASCOM::GetGuideRates() returns %u %.4f %.4f", bError,
        bError ? 0.0 : *pDecGuideRate, bError ? 0.0 : *pRAGuideRate);

    return bError;
}
Example #4
0
 bool Entry()
 {
     GITObjRef scope(sa->m_gitEntry);
     // ... set the Connected property to true....
     if (!scope.PutProp(sa->dispid_connected, true))
     {
         SetErrorMsg(ExcepMsg(scope.Excep()));
         return true;
     }
     return false;
 }
Example #5
0
 bool Entry()
 {
     GITObjRef dobj(cam->m_gitEntry);
     // ... set the Connected property to true....
     if (!dobj.PutProp(L"Connected", true))
     {
         SetErrorMsg(ExcepMsg(dobj.Excep()));
         return true;
     }
     return false;
 }
Example #6
0
bool ScopeASCOM::GetSiteLatLong(double *latitude, double *longitude)
{
    if (dispid_sitelatitude == DISPID_UNKNOWN || dispid_sitelongitude == DISPID_UNKNOWN)
        return true;

    bool bError = false;

    try
    {
        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: cannot get site latitude/longitude when not connected");
        }

        GITObjRef scope(m_gitEntry);

        Variant vLat;

        if (!scope.GetProp(&vLat, dispid_sitelatitude))
        {
            throw ERROR_INFO("ASCOM Scope: get site latitude failed: " + ExcepMsg(scope.Excep()));
        }

        Variant vLong;

        if (!scope.GetProp(&vLong, dispid_sitelongitude))
        {
            throw ERROR_INFO("ASCOM Scope: get site longitude failed: " + ExcepMsg(scope.Excep()));
        }

        *latitude = vLat.dblVal;
        *longitude = vLong.dblVal;
    }
    catch (wxString Msg)
    {
        bError = true;
        POSSIBLY_UNUSED(Msg);
    }

    return bError;
}
Example #7
0
void Camera_ASCOMLateClass::ShowPropertyDialog(void)
{
    DispatchObj camera;

    if (Create(&camera, NULL))
    {
        Variant res;
        if (!camera.InvokeMethod(&res, L"SetupDialog"))
        {
            pFrame->Alert(ExcepMsg(camera.Excep()));
        }
    }
}
Example #8
0
static bool ChooseASCOMScope(BSTR *res)
{
    DispatchObj chooser;
    if (!chooser.Create(L"DriverHelper.Chooser"))
    {
        Debug.AddLine("Chooser instantiate failed: " + ExcepMsg(chooser.Excep()));
        wxMessageBox(_("Failed to find the ASCOM Chooser. Make sure it is installed"), _("Error"), wxOK | wxICON_ERROR);
        return false;
    }

    if (!chooser.PutProp(L"DeviceType", L"Telescope"))
    {
        Debug.AddLine("Chooser put prop failed: " + ExcepMsg(chooser.Excep()));
        wxMessageBox(_("Failed to set the Chooser's type to Telescope. Something is wrong with ASCOM"), _("Error"), wxOK | wxICON_ERROR);
        return false;
    }

    // Look in Registry to see if there is a default
    wxString wx_ProgID = pConfig->Global.GetString("/scope/ascom/ScopeID", _T(""));
    BSTR bstr_ProgID = wxBasicString(wx_ProgID).Get();

    Variant vchoice;
    if (!chooser.InvokeMethod(&vchoice, L"Choose", bstr_ProgID))
    {
        wxMessageBox(_("Failed to run the Telescope Chooser. Something is wrong with ASCOM"), _("Error"), wxOK | wxICON_ERROR);
        return false;
    }

    if (SysStringLen(vchoice.bstrVal) == 0)
        return false; // use hit cancel

    // Save name of scope
    pConfig->Global.SetString("/scope/ascom/ScopeID", vchoice.bstrVal);

    *res = vchoice.bstrVal;
    return true;
}
Example #9
0
bool Camera_ASCOMLateClass::Disconnect()
{
    if (!Connected)
    {
        Debug.AddLine("ASCOM camera: attempt to disconnect when not connected");
        return false;
    }

    { // scope
        GITObjRef cam(m_gitEntry);

        if (!cam.PutProp(L"Connected", false))
        {
            Debug.AddLine(ExcepMsg("ASCOM disconnect", cam.Excep()));
            pFrame->Alert(ExcepMsg(_("ASCOM driver problem -- cannot disconnect"), cam.Excep()));
            return true;
        }
    } // scope

    m_gitEntry.Unregister();

    Connected = false;
    return false;
}
Example #10
0
bool ScopeASCOM::IsSlewing(DispatchObj *scope)
{
    Variant vRes;
    if (!scope->GetProp(&vRes, dispid_isslewing))
    {
        Debug.AddLine("ScopeASCOM::IsSlewing failed: " + ExcepMsg(scope->Excep()));
        pFrame->Alert(_("ASCOM driver failed checking Slewing"));
        return false;
    }

    bool result = vRes.boolVal == VARIANT_TRUE;

    Debug.AddLine("IsSlewing returns %d", result);

    return result;
}
Example #11
0
static bool ASCOM_IsMoving(IDispatch *cam)
{
    DISPPARAMS dispParms;
    dispParms.cArgs = 0;
    dispParms.rgvarg = NULL;
    dispParms.cNamedArgs = 0;
    dispParms.rgdispidNamedArgs = NULL;

    HRESULT hr;
    EXCEPINFO excep;
    Variant vRes;

    if (FAILED(hr = cam->Invoke(dispid_ispulseguiding, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParms, &vRes, &excep, NULL)))
    {
        LogExcep(hr, "invoke ispulseguiding", excep);
        pFrame->Alert(ExcepMsg(_("ASCOM driver failed checking IsPulseGuiding. See the debug log for more information."), excep));
        return false;
    }

    return vRes.boolVal == VARIANT_TRUE;
}
Example #12
0
PierSide ScopeASCOM::SideOfPier(void)
{
    PierSide pierSide = PIER_SIDE_UNKNOWN;

    try
    {
        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: cannot get side of pier when not connected");
        }

        if (dispid_sideofpier == DISPID_UNKNOWN)
        {
            throw THROW_INFO("ASCOM Scope: not capable of getting side of pier");
        }

        GITObjRef scope(m_gitEntry);

        Variant vRes;

        if (!scope.GetProp(&vRes, dispid_sideofpier))
        {
            throw ERROR_INFO("ASCOM Scope: SideOfPier failed: " + ExcepMsg(scope.Excep()));
        }

        switch (vRes.intVal) {
        case 0: pierSide = PIER_SIDE_EAST; break;
        case 1: pierSide = PIER_SIDE_WEST; break;
        }
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
    }

    Debug.AddLine("ScopeASCOM::SideOfPier() returns %d", pierSide);

    return pierSide;
}
Example #13
0
// Special purpose function to return the guiding declination (radians) - either the actual scope position or the
// default values defined in mount.cpp.  Doesn't throw exceptions to callers.
double ScopeASCOM::GetGuidingDeclination(void)
{
    double dReturn = Scope::GetDefGuidingDeclination();

    try
    {
        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: cannot get Declination when not connected to mount");
        }

        if (!m_bCanGetCoordinates)
        {
            throw THROW_INFO("!m_bCanGetCoordinates");
        }

        GITObjRef scope(m_gitEntry);

        Variant vRes;
        if (!scope.GetProp(&vRes, dispid_declination))
        {
            throw ERROR_INFO("GetDeclination() fails: " + ExcepMsg(scope.Excep()));
        }

        dReturn = radians(vRes.dblVal);
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
        m_bCanGetCoordinates = false;
    }

    Debug.AddLine("ScopeASCOM::GetDeclination() returns %.1f", degrees(dReturn));

    return dReturn;
}
Example #14
0
bool ScopeASCOM::Connect(void)
{
    bool bError = false;

    try
    {
        Debug.AddLine("Connecting");

        if (IsConnected())
        {
            wxMessageBox("Scope already connected",_("Error"));
            throw ERROR_INFO("ASCOM Scope: Connected - Already Connected");
        }

        DispatchObj pScopeDriver;

        if (!Create(pScopeDriver))
        {
            wxMessageBox(_T("Could not establish instance of ") + m_choice, _("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not establish ASCOM Scope instance");
        }

        // --- get the dispatch IDs we need ...

        // ... get the dispatch ID for the Connected property ...
        if (!pScopeDriver.GetDispatchId(&dispid_connected, L"Connected"))
        {
            wxMessageBox(_T("ASCOM driver problem -- cannot connect"),_("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not get the dispatch id for the Connected property");
        }

        // ... get the dispatch ID for the "IsPulseGuiding" property ....
        m_bCanCheckPulseGuiding = true;
        if (!pScopeDriver.GetDispatchId(&dispid_ispulseguiding, L"IsPulseGuiding"))
        {
            m_bCanCheckPulseGuiding = false;
            Debug.AddLine("cannot get dispid_ispulseguiding");
            // don't fail if we can't get the status on this - can live without it as it's really a safety net for us
        }

        // ... get the dispatch ID for the "Slewing" property ....
        if (!pScopeDriver.GetDispatchId(&dispid_isslewing, L"Slewing"))
        {
            wxMessageBox(_T("ASCOM driver missing the Slewing property"),_("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not get the dispatch id for the Slewing property");
        }

        // ... get the dispatch ID for the "PulseGuide" property ....
        if (!pScopeDriver.GetDispatchId(&dispid_pulseguide, L"PulseGuide"))
        {
            wxMessageBox(_T("ASCOM driver missing the PulseGuide property"),_("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not get the dispatch id for the PulseGuide property");
        }

        // ... get the dispatch ID for the "Declination" property ....
        m_bCanGetCoordinates = true;
        if (!pScopeDriver.GetDispatchId(&dispid_declination, L"Declination"))
        {
            m_bCanGetCoordinates = false;
            Debug.AddLine("cannot get dispid_declination");
        }
        else if (!pScopeDriver.GetDispatchId(&dispid_rightascension, L"RightAscension"))
        {
            Debug.AddLine("cannot get dispid_rightascension");
            m_bCanGetCoordinates = false;
        }
        else if (!pScopeDriver.GetDispatchId(&dispid_siderealtime, L"SiderealTime"))
        {
            Debug.AddLine("cannot get dispid_siderealtime");
            m_bCanGetCoordinates = false;
        }

        if (!pScopeDriver.GetDispatchId(&dispid_sitelatitude, L"SiteLatitude"))
        {
            Debug.AddLine("cannot get dispid_sitelatitude");
        }
        if (!pScopeDriver.GetDispatchId(&dispid_sitelongitude, L"SiteLongitude"))
        {
            Debug.AddLine("cannot get dispid_sitelongitude");
        }

        m_bCanSlew = true;
        if (!pScopeDriver.GetDispatchId(&dispid_slewtocoordinates, L"SlewToCoordinates"))
        {
            m_bCanSlew = false;
            Debug.AddLine("cannot get dispid_slewtocoordinates");
        }

        // ... get the dispatch IDs for the two guide rate properties - if we can't get them, no sweat, doesn't matter for actual guiding
        // Used for things like calibration sanity checking, backlash clearing, etc.
        m_bCanGetGuideRates = true;         // Likely case, required for any ASCOM driver at V2 or later
        if (!pScopeDriver.GetDispatchId(&dispid_decguiderate, L"GuideRateDeclination"))
        {
            Debug.AddLine("cannot get dispid_decguiderate");
            m_bCanGetGuideRates = false;
            // don't throw if we can't get this one
        }
        else if (!pScopeDriver.GetDispatchId(&dispid_raguiderate, L"GuideRateRightAscension"))
        {
            Debug.AddLine("cannot get dispid_raguiderate");
            m_bCanGetGuideRates = false;
            // don't throw if we can't get this one
        }

        if (!pScopeDriver.GetDispatchId(&dispid_sideofpier, L"SideOfPier"))
        {
            Debug.AddLine("cannot get dispid_sideofpier");
            dispid_sideofpier = DISPID_UNKNOWN;
        }

        if (!pScopeDriver.GetDispatchId(&dispid_abortslew, L"AbortSlew"))
        {
            Debug.AddLine("cannot get dispid_abortslew");
            dispid_abortslew = DISPID_UNKNOWN;
        }

        struct ConnectInBg : public ConnectMountInBg
        {
            ScopeASCOM *sa;
            ConnectInBg(ScopeASCOM *sa_) : sa(sa_) { }
            bool Entry()
            {
                GITObjRef scope(sa->m_gitEntry);
                // ... set the Connected property to true....
                if (!scope.PutProp(sa->dispid_connected, true))
                {
                    SetErrorMsg(ExcepMsg(scope.Excep()));
                    return true;
                }
                return false;
            }
        };
        ConnectInBg bg(this);

        // set the Connected property to true in a background thread
        if (bg.Run())
        {
            wxMessageBox(_T("ASCOM driver problem during connection: ") + bg.GetErrorMsg(),
                _("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not set Connected property to true");
        }

        // get the scope name
        Variant vRes;
        if (!pScopeDriver.GetProp(&vRes, L"Name"))
        {
            wxMessageBox(_T("ASCOM driver problem getting Name property"), _("Error"), wxOK | wxICON_ERROR);
            throw ERROR_INFO("ASCOM Scope: Could not get the scope name: " + ExcepMsg(pScopeDriver.Excep()));
        }

        m_Name = vRes.bstrVal;

        Debug.AddLine("Scope reports its name as " + m_Name);

        m_abortSlewWhenGuidingStuck = false;

        if (m_Name == _T("Gemini Telescope .NET"))
        {
            // Gemini2 firmware (2013 Oct 13 version, perhaps others) has been found to contain a
            // bug where a pulse guide command can fail to complete, with the Guiding property
            // returning true forever. The firmware developer suggests that PHD2 should issue an
            // AbortSlew when this condition is detected.
            Debug.AddLine("ASCOM scope: enabling stuck guide pulse workaround");
            m_abortSlewWhenGuidingStuck = true;
        }

        // see if we can pulse guide
        m_bCanPulseGuide = true;
        if (!pScopeDriver.GetProp(&vRes, L"CanPulseGuide") || !vRes.boolVal)
        {
            Debug.AddLine("Connecting to ASCOM scope that does not support PulseGuide");
            m_bCanPulseGuide = false;
        }

        // see if we can slew
        if (m_bCanSlew)
        {
            if (!pScopeDriver.GetProp(&vRes, L"CanSlew"))
            {
                Debug.AddLine("ASCOM scope got error invoking CanSlew: " + ExcepMsg(pScopeDriver.Excep()));
                m_bCanSlew = false;
            }
            else if (!vRes.boolVal)
            {
                Debug.AddLine("ASCOM scope reports CanSlew = false");
                m_bCanSlew = false;
            }
        }

        pFrame->SetStatusText(Name()+_(" connected"));
        Scope::Connect();

        Debug.AddLine("Connect success");
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
        bError = true;
    }

    return bError;
}
Example #15
0
wxArrayString ScopeASCOM::EnumAscomScopes()
{
    wxArrayString list;

    try
    {
        DispatchObj profile;
        if (!profile.Create(L"ASCOM.Utilities.Profile"))
            throw ERROR_INFO("ASCOM Scope: could not instantiate ASCOM profile class ASCOM.Utilities.Profile. Is ASCOM installed?");

        Variant res;
        if (!profile.InvokeMethod(&res, L"RegisteredDevices", L"Telescope"))
            throw ERROR_INFO("ASCOM Scope: could not query registered telescope devices: " + ExcepMsg(profile.Excep()));

        DispatchClass ilist_class;
        DispatchObj ilist(res.pdispVal, &ilist_class);

        Variant vcnt;
        if (!ilist.GetProp(&vcnt, L"Count"))
            throw ERROR_INFO("ASCOM Scope: could not query registered telescopes: " + ExcepMsg(ilist.Excep()));

        // if we made it this far ASCOM is installed and apprears sane, so add the chooser
        list.Add(_T("ASCOM Telescope Chooser"));

        unsigned int const count = vcnt.intVal;
        DispatchClass kvpair_class;

        for (unsigned int i = 0; i < count; i++)
        {
            Variant kvpres;
            if (ilist.GetProp(&kvpres, L"Item", i))
            {
                DispatchObj kvpair(kvpres.pdispVal, &kvpair_class);
                Variant vkey, vval;
                if (kvpair.GetProp(&vkey, L"Key") && kvpair.GetProp(&vval, L"Value"))
                {
                    wxString ascomName = vval.bstrVal;
                    wxString displName = displayName(ascomName);
                    wxString progid = vkey.bstrVal;
                    s_progid[displName] = progid;
                    list.Add(displName);
                }
            }
        }
    }
    catch (const wxString& msg)
    {
        POSSIBLY_UNUSED(msg);
    }

    return list;
}
Example #16
0
inline static void LogExcep(HRESULT hr, const wxString& prefix, const EXCEPINFO& excep)
{
    Debug.AddLine(wxString::Format("%s: [%x] %s", prefix, hr, _com_error(hr).ErrorMessage()));
    if (hr == DISP_E_EXCEPTION)
        Debug.AddLine(ExcepMsg(prefix, excep));
}
Example #17
0
bool Camera_ASCOMLateClass::Capture(int duration, usImage& img, int options, const wxRect& subframeArg)
{
    bool retval = false;
    bool takeSubframe = UseSubframes;
    wxRect subframe(subframeArg);

    if (subframe.width <= 0 || subframe.height <= 0)
    {
        takeSubframe = false;
    }

    bool binning_changed = false;
    if (Binning != m_curBin)
    {
        FullSize = wxSize(m_maxSize.x / Binning, m_maxSize.y / Binning);
        binning_changed = true;
    }

    // Program the size
    if (!takeSubframe)
    {
        subframe = wxRect(0, 0, FullSize.GetWidth(), FullSize.GetHeight());
    }

    if (img.Init(FullSize))
    {
        pFrame->Alert(_("Cannot allocate memory to download image from camera"));
        return true;
    }

    GITObjRef cam(m_gitEntry);

    EXCEPINFO excep;

    if (binning_changed)
    {
        if (ASCOM_SetBin(cam.IDisp(), Binning, &excep))
        {
            pFrame->Alert(_("The ASCOM camera failed to set binning. See the debug log for more information."));
            return true;
        }
        m_curBin = Binning;
    }

    if (subframe != m_roi)
    {
        ASCOM_SetROI(cam.IDisp(), subframe, &excep);
        m_roi = subframe;
    }

    bool takeDark = HasShutter && ShutterClosed;

    // Start the exposure
    if (ASCOM_StartExposure(cam.IDisp(), (double)duration / 1000.0, takeDark, &excep))
    {
        Debug.AddLine(ExcepMsg("ASCOM_StartExposure failed", excep));
        pFrame->Alert(ExcepMsg(_("ASCOM error -- Cannot start exposure with given parameters"), excep));
        return true;
    }

    CameraWatchdog watchdog(duration, GetTimeoutMs());

    if (duration > 100)
    {
        // wait until near end of exposure
        if (WorkerThread::MilliSleep(duration - 100, WorkerThread::INT_ANY) &&
            (WorkerThread::TerminateRequested() || AbortExposure()))
        {
            return true;
        }
    }

    while (true)  // wait for image to finish and d/l
    {
        wxMilliSleep(20);
        bool ready;
        EXCEPINFO excep;
        if (ASCOM_ImageReady(cam.IDisp(), &ready, &excep))
        {
            Debug.AddLine(ExcepMsg("ASCOM_ImageReady failed", excep));
            pFrame->Alert(ExcepMsg(_("Exception thrown polling camera"), excep));
            return true;
        }
        if (ready)
            break;
        if (WorkerThread::InterruptRequested() &&
            (WorkerThread::TerminateRequested() || AbortExposure()))
        {
            return true;
        }
        if (watchdog.Expired())
        {
            DisconnectWithAlert(CAPT_FAIL_TIMEOUT);
            return true;
        }
    }

    // Get the image
    if (ASCOM_Image(cam.IDisp(), img, takeSubframe, subframe, &excep))
    {
        Debug.AddLine(ExcepMsg(_T("ASCOM_Image failed"), excep));
        pFrame->Alert(ExcepMsg(_("Error reading image"), excep));
        return true;
    }

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

    return false;
}
Example #18
0
bool ScopeASCOM::Disconnect(void)
{
    bool bError = false;

    try
    {
        Debug.AddLine("Disconnecting");

        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: attempt to disconnect when not connected");
        }

        // Setting the Connected property to false will cause the scope to be disconnected for all
        // ASCOM clients that are connected to the scope, and we do not want this!
        bool const disconnectAscomDriver = false;
        if (disconnectAscomDriver)
        {
            GITObjRef scope(m_gitEntry);

            // Set the Connected property to false
            if (!scope.PutProp(dispid_connected, false))
            {
                pFrame->Alert(_("ASCOM driver problem during disconnect"));
                throw ERROR_INFO("ASCOM Scope: Could not set Connected property to false: " + ExcepMsg(scope.Excep()));
            }
        }

        m_gitEntry.Unregister();

        Debug.AddLine("Disconnected Successfully");
    }
    catch (const wxString& Msg)
    {
        POSSIBLY_UNUSED(Msg);
        bError = true;
    }

    Scope::Disconnect();

    return bError;
}
Example #19
0
wxString ExcepMsg(const wxString& prefix, const EXCEPINFO& excep)
{
    return prefix + ":\n" + ExcepMsg(excep);
}
Example #20
0
Mount::MOVE_RESULT ScopeASCOM::Guide(GUIDE_DIRECTION direction, int duration)
{
    MOVE_RESULT result = MOVE_OK;

    try
    {
        Debug.AddLine("Guiding  Dir = %d, Dur = %d", direction, duration);

        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: attempt to guide when not connected");
        }

        if (!m_bCanPulseGuide)
        {
            // Could happen if move command is issued on the Aux mount or CanPulseGuide property got changed on the fly
            pFrame->Alert(_("ASCOM driver does not support PulseGuide"));
            throw ERROR_INFO("ASCOM scope: guide command issued but PulseGuide not supported");
        }

        GITObjRef scope(m_gitEntry);

        // First, check to see if already moving

        CheckSlewing(&scope, &result);

        if (IsGuiding(&scope))
        {
            Debug.AddLine("Entered PulseGuideScope while moving");
            int i;
            for (i = 0; i < 20; i++)
            {
                wxMilliSleep(50);

                CheckSlewing(&scope, &result);

                if (!IsGuiding(&scope))
                    break;

                Debug.AddLine("Still moving");
            }
            if (i == 20)
            {
                Debug.AddLine("Still moving after 1s - aborting");
                throw ERROR_INFO("ASCOM Scope: scope is still moving after 1 second");
            }
            else
            {
                Debug.AddLine("Movement stopped - continuing");
            }
        }

        // Do the move

        VARIANTARG rgvarg[2];
        rgvarg[1].vt = VT_I2;
        rgvarg[1].iVal = direction;
        rgvarg[0].vt = VT_I4;
        rgvarg[0].lVal = (long) duration;

        DISPPARAMS dispParms;
        dispParms.cArgs = 2;
        dispParms.rgvarg = rgvarg;
        dispParms.cNamedArgs = 0;
        dispParms.rgdispidNamedArgs = NULL;

        wxStopWatch swatch;

        HRESULT hr;
        EXCEPINFO excep;
        Variant vRes;

        if (FAILED(hr = scope.IDisp()->Invoke(dispid_pulseguide, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
            &dispParms, &vRes, &excep, NULL)))
        {
            Debug.AddLine(wxString::Format("pulseguide: [%x] %s", hr, _com_error(hr).ErrorMessage()));

            // Make sure nothing got by us and the mount can really handle pulse guide - HIGHLY unlikely
            if (scope.GetProp(&vRes, L"CanPulseGuide") && !vRes.boolVal)
            {
                Debug.AddLine("Tried to guide mount that has no PulseGuide support");
                // This will trigger a nice alert the next time through Guide
                m_bCanPulseGuide = false;
            }
            throw ERROR_INFO("ASCOM Scope: pulseguide command failed: " + ExcepMsg(excep));
        }

        long elapsed = swatch.Time();
        if (elapsed < (long)duration)
        {
            unsigned long rem = (unsigned long)((long)duration - elapsed);

            Debug.AddLine("PulseGuide returned control before completion, sleep %lu", rem + 10);

            if (WorkerThread::MilliSleep(rem + 10))
                throw ERROR_INFO("ASCOM Scope: thread terminate requested");
        }

        if (IsGuiding(&scope))
        {
            Debug.AddLine("scope still moving after pulse duration time elapsed");

            // try waiting a little longer. If scope does not stop moving after 1 second, try doing AbortSlew
            // if it still does not stop after 2 seconds, bail out with an error

            enum { GRACE_PERIOD_MS = 1000,
                   TIMEOUT_MS = GRACE_PERIOD_MS + 1000, };

            bool timeoutExceeded = false;
            bool didAbortSlew = false;

            while (true)
            {
                ::wxMilliSleep(20);

                if (WorkerThread::InterruptRequested())
                    throw ERROR_INFO("ASCOM Scope: thread interrupt requested");

                CheckSlewing(&scope, &result);

                if (!IsGuiding(&scope))
                {
                    Debug.AddLine("scope move finished after %ld + %ld ms", (long)duration, swatch.Time() - (long)duration);
                    break;
                }

                long now = swatch.Time();

                if (!didAbortSlew && now > duration + GRACE_PERIOD_MS && m_abortSlewWhenGuidingStuck)
                {
                    Debug.AddLine("scope still moving after %ld + %ld ms, try aborting slew", (long)duration, now - (long)duration);
                    AbortSlew(&scope);
                    didAbortSlew = true;
                    continue;
                }

                if (now > duration + TIMEOUT_MS)
                {
                    timeoutExceeded = true;
                    break;
                }
            }

            if (timeoutExceeded && IsGuiding(&scope))
            {
                throw ERROR_INFO("timeout exceeded waiting for guiding pulse to complete");
            }
        }
    }
    catch (const wxString& msg)
    {
        POSSIBLY_UNUSED(msg);

        if (result == MOVE_OK)
        {
            result = MOVE_ERROR;
            pFrame->Alert(_("PulseGuide command to mount has failed - guiding is likely to be ineffective."));
        }
    }

    if (result == MOVE_STOP_GUIDING)
    {
        pFrame->Alert(_("Guiding stopped: the scope started slewing."));
    }

    return result;
}
Example #21
0
bool ScopeASCOM::Disconnect(void)
{
    bool bError = false;

    try
    {
        Debug.AddLine("Disconnecting");

        if (!IsConnected())
        {
            throw ERROR_INFO("ASCOM Scope: attempt to disconnect when not connected");
        }

        GITObjRef scope(m_gitEntry);

        // ... set the Connected property to false....
        if (!scope.PutProp(dispid_connected, false))
        {
            pFrame->Alert(_("ASCOM driver problem during disconnect"));
            throw ERROR_INFO("ASCOM Scope: Could not set Connected property to false: " + ExcepMsg(scope.Excep()));
        }

        Debug.AddLine("Disconnected Successfully");
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
        bError = true;
    }

    Scope::Disconnect();

    return bError;
}
Example #22
0
bool Camera_ASCOMLateClass::Connect(const wxString& camId)
{
    DispatchClass driver_class;
    DispatchObj driver(&driver_class);

    // create the COM object
    if (!Create(&driver, &driver_class))
    {
        pFrame->Alert(_("Could not create ASCOM camera object. See the debug log for more information."));
        return true;
    }

    struct ConnectInBg : public ConnectCameraInBg
    {
        Camera_ASCOMLateClass *cam;
        ConnectInBg(Camera_ASCOMLateClass *cam_) : cam(cam_) { }
        bool Entry()
        {
            GITObjRef dobj(cam->m_gitEntry);
            // ... set the Connected property to true....
            if (!dobj.PutProp(L"Connected", true))
            {
                SetErrorMsg(ExcepMsg(dobj.Excep()));
                return true;
            }
            return false;
        }
    };
    ConnectInBg bg(this);

    if (bg.Run())
    {
        pFrame->Alert(_("ASCOM driver problem: Connect") + ":\n" + bg.GetErrorMsg());
        return true;
    }

    Variant vname;
    if (driver.GetProp(&vname, L"Name"))
    {
        Name = vname.bstrVal;
        Debug.AddLine(wxString::Format("setting camera Name = %s", Name));
    }

    // See if we have an onboard guider output
    Variant vRes;
    if (!driver.GetProp(&vRes, L"CanPulseGuide"))
    {
        Debug.AddLine(ExcepMsg("CanPulseGuide", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the CanPulseGuide property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    m_hasGuideOutput = ((vRes.boolVal != VARIANT_FALSE) ? true : false);

    if (!driver.GetProp(&vRes, L"CanAbortExposure"))
    {
        Debug.AddLine(ExcepMsg("CanAbortExposure", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the CanAbortExposure property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    m_canAbortExposure = vRes.boolVal != VARIANT_FALSE ? true : false;

    if (!driver.GetProp(&vRes, L"CanStopExposure"))
    {
        Debug.AddLine(ExcepMsg("CanStopExposure", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the CanStopExposure property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    m_canStopExposure = vRes.boolVal != VARIANT_FALSE ? true : false;

    // Check if we have a shutter
    if (driver.GetProp(&vRes, L"HasShutter"))
    {
        HasShutter = ((vRes.boolVal != VARIANT_FALSE) ? true : false);
    }

    // Get the image size of a full frame

    if (!driver.GetProp(&vRes, L"CameraXSize"))
    {
        Debug.AddLine(ExcepMsg("CameraXSize", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the CameraXSize property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    m_maxSize.SetWidth((int) vRes.lVal);

    if (!driver.GetProp(&vRes, L"CameraYSize"))
    {
        Debug.AddLine(ExcepMsg("CameraYSize", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the CameraYSize property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    m_maxSize.SetHeight((int) vRes.lVal);

    if (!driver.GetProp(&vRes, L"MaxADU"))
    {
        Debug.AddLine(ExcepMsg("MaxADU", driver.Excep()));
        m_bitsPerPixel = 16;  // assume 16 BPP
    }
    else
    {
        m_bitsPerPixel = vRes.intVal <= 255 ? 8 : 16;
    }

    // Get the interface version of the driver

    DriverVersion = 1;
    if (driver.GetProp(&vRes, L"InterfaceVersion"))
    {
        DriverVersion = vRes.iVal;
    }

    if (DriverVersion > 1 &&  // We can check the color sensor status of the cam
        driver.GetProp(&vRes, L"SensorType") &&
        vRes.iVal > 1)
    {
        Color = true;
    }

    // Get pixel size in micons

    if (!driver.GetProp(&vRes, L"PixelSizeX"))
    {
        Debug.AddLine(ExcepMsg("PixelSizeX", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the PixelSizeX property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    PixelSize = (double) vRes.dblVal;

    if (!driver.GetProp(&vRes, L"PixelSizeY"))
    {
        Debug.AddLine(ExcepMsg("PixelSizeY", driver.Excep()));
        pFrame->Alert(_("ASCOM driver missing the PixelSizeY property. Please report this error to your ASCOM driver provider."));
        return true;
    }
    if ((double) vRes.dblVal > PixelSize)
        PixelSize = (double) vRes.dblVal;

    short maxBinX = 1, maxBinY = 1;
    if (driver.GetProp(&vRes, L"MaxBinX"))
        maxBinX = vRes.iVal;
    if (driver.GetProp(&vRes, L"MaxBinY"))
        maxBinY = vRes.iVal;
    MaxBinning = wxMin(maxBinX, maxBinY);
    Debug.AddLine("ASCOM camera: MaxBinning is %hu", MaxBinning);
    if (Binning > MaxBinning)
        Binning = MaxBinning;
    m_curBin = Binning;

    // Get the dispids we'll need for more routine things
    if (!GetDispid(&dispid_setxbin, driver, L"BinX"))
        return true;

    if (!GetDispid(&dispid_setybin, driver, L"BinY"))
        return true;

    if (!GetDispid(&dispid_startx, driver, L"StartX"))
        return true;

    if (!GetDispid(&dispid_starty, driver, L"StartY"))
        return true;

    if (!GetDispid(&dispid_numx, driver, L"NumX"))
        return true;

    if (!GetDispid(&dispid_numy, driver, L"NumY"))
        return true;

    if (!GetDispid(&dispid_imageready, driver, L"ImageReady"))
        return true;

    if (!GetDispid(&dispid_imagearray, driver, L"ImageArray"))
        return true;

    if (!GetDispid(&dispid_startexposure, driver, L"StartExposure"))
        return true;

    if (!GetDispid(&dispid_abortexposure, driver, L"AbortExposure"))
        return true;

    if (!GetDispid(&dispid_stopexposure, driver, L"StopExposure"))
        return true;

    if (!GetDispid(&dispid_pulseguide, driver, L"PulseGuide"))
        return true;

    if (!GetDispid(&dispid_ispulseguiding, driver, L"IsPulseGuiding"))
        return true;

    // Program some defaults -- full size and binning
    EXCEPINFO excep;
    if (ASCOM_SetBin(driver.IDisp(), Binning, &excep))
    {
        // only make this error fatal if the camera supports binning > 1
        if (MaxBinning > 1)
        {
            pFrame->Alert(_("The ASCOM camera failed to set binning. See the debug log for more information."));
            return true;
        }
    }
    FullSize = wxSize(m_maxSize.x / Binning, m_maxSize.y / Binning);
    m_roi = FullSize;
    ASCOM_SetROI(driver.IDisp(), FullSize, &excep);

    Connected = true;

    return false;
}