diff --git a/kstars/ekos/guide/externalguide/phd2.h b/kstars/ekos/guide/externalguide/phd2.h --- a/kstars/ekos/guide/externalguide/phd2.h +++ b/kstars/ekos/guide/externalguide/phd2.h @@ -91,7 +91,7 @@ enum PHD2ResultType { NO_RESULT, - //capture_single_frame + CAPTURE_SINGLE_FRAME, //capture_single_frame CLEAR_CALIBRATION_COMMAND_RECEIVED, //clear_calibration DITHER_COMMAND_RECEIVED, //dither //find_star @@ -103,11 +103,11 @@ //get_calibration_data IS_EQUIPMENT_CONNECTED, //get_connected //get_cooler_status - //get_current_equipment + GET_CURRENT_EQUIPMENT, //get_current_equipment DEC_GUIDE_MODE, //get_dec_guide_mode EXPOSURE_TIME, //get_exposure EXPOSURE_DURATIONS, //get_exposure_durations - //get_lock_position + LOCK_POSITION, //get_lock_position //get_lock_shift_enabled //get_lock_shift_params //get_paused @@ -120,13 +120,13 @@ //get_use_subframes GUIDE_COMMAND_RECEIVED, //guide //guide_pulse - //loop + LOOP, //loop //save_image //set_algo_param CONNECTION_RESULT, //set_connected SET_DEC_GUIDE_MODE_COMMAND_RECEIVED, //set_dec_guide_mode SET_EXPOSURE_COMMAND_RECEIVED, //set_exposure - //set_lock_position + SET_LOCK_POSITION, //set_lock_position //set_lock_shift_enabled //set_lock_shift_params SET_PAUSED_COMMAND_RECEIVED, //set_paused @@ -148,7 +148,7 @@ //These are the PHD2 Methods. Only some are implemented in Ekos. - //capture_single_frame + void captureSingleFrame(); //capture_single_frame bool clearCalibration() override; //clear_calibration bool dither(double pixels) override; //dither //find_star @@ -160,11 +160,11 @@ //get_calibration_data void checkIfEquipmentConnected(); //get_connected //get_cooler_status - //get_current_equipment + void requestCurrentEquipmentUpdate(); //get_current_equipment void checkDEGuideMode(); //get_dec_guide_mode void requestExposureTime(); //get_exposure void requestExposureDurations(); //get_exposure_durations - //get_lock_position + void requestLockPosition(); //get_lock_position //get_lock_shift_enabled //get_lock_shift_params //get_paused @@ -177,13 +177,13 @@ //get_use_subframes bool guide() override; //guide //guide_pulse - //loop + void loop(); //loop //save_image //set_algo_param void connectEquipment(bool enable);//set_connected void requestSetDEGuideMode(bool deEnabled, bool nEnabled, bool sEnabled); //set_dec_guide_mode void requestSetExposureTime(int time); //set_exposure - //set_lock_position + void setLockPosition(double x, double y); //set_lock_position //set_lock_shift_enabled //set_lock_shift_params bool suspend() override; //set_paused @@ -195,6 +195,13 @@ bool calibrate() override; //Note PHD2 does not have a separate calibrate command. This is unused. void setGuideView(FITSView *guideView); + QString getCurrentCamera(){ return currentCamera; } + QString getCurrentMount(){ return currentMount; } + QString getCurrentAuxMount(){ return currentAuxMount; } + + bool isCurrentCameraNotInEkos(){ return currentCameraIsNotInEkos; } + void setCurrentCameraIsNotInEkos(bool enable) {currentCameraIsNotInEkos = enable;} + private slots: void readPHD2(); @@ -253,6 +260,12 @@ double pixelScale = 0; QString logValidExposureTimes; + + QString currentCamera; + QString currentMount; + QString currentAuxMount; + bool currentCameraIsNotInEkos; + }; } diff --git a/kstars/ekos/guide/externalguide/phd2.cpp b/kstars/ekos/guide/externalguide/phd2.cpp --- a/kstars/ekos/guide/externalguide/phd2.cpp +++ b/kstars/ekos/guide/externalguide/phd2.cpp @@ -67,7 +67,7 @@ //This list of available PHD Methods is on https://github.com/OpenPHDGuiding/phd2/wiki/EventMonitoring //Only some of the methods are implemented. The ones that say COMMAND_RECEIVED simply return a 0 saying the command was received. - //capture_single_frame + methodResults["capture_single_frame"] = CAPTURE_SINGLE_FRAME; methodResults["clear_calibration"] = CLEAR_CALIBRATION_COMMAND_RECEIVED; methodResults["dither"] = DITHER_COMMAND_RECEIVED; //find_star @@ -79,11 +79,11 @@ //get_calibration_data methodResults["get_connected"] = IS_EQUIPMENT_CONNECTED; //get_cooler_status - //get_current_equipment + methodResults["get_current_equipment"] = GET_CURRENT_EQUIPMENT; methodResults["get_dec_guide_mode"] = DEC_GUIDE_MODE; methodResults["get_exposure"] = EXPOSURE_TIME; methodResults["get_exposure_durations"] = EXPOSURE_DURATIONS; - //get_lock_position + methodResults["get_lock_position"] = LOCK_POSITION; //get_lock_shift_enabled //get_lock_shift_params //get_paused @@ -96,13 +96,13 @@ //get_use_subframes methodResults["guide"] = GUIDE_COMMAND_RECEIVED; //guide_pulse - //loop + methodResults["loop"] = LOOP; //save_image //set_algo_param methodResults["set_connected"] = CONNECTION_RESULT; methodResults["set_dec_guide_mode"] = SET_DEC_GUIDE_MODE_COMMAND_RECEIVED; methodResults["set_exposure"] = SET_EXPOSURE_COMMAND_RECEIVED; - //set_lock_position + methodResults["set_lock_position"] = SET_LOCK_POSITION; //set_lock_shift_enabled //set_lock_shift_params methodResults["set_paused"] = SET_PAUSED_COMMAND_RECEIVED; @@ -284,6 +284,7 @@ case StartGuiding: setEquipmentConnected(); updateGuideParameters(); + requestCurrentEquipmentUpdate(); // Do not report guiding as started because it will start scheduled capture before guiding is settled // just print the log message and GUIDE_STARTED status will be set in SettleDone // phd2 will always send SettleDone event @@ -473,8 +474,13 @@ emit newAxisSigma(sqrt(total_sqr_RA_error / errorLog.size()), sqrt(total_sqr_DE_error / errorLog.size())); } - - requestStarImage(32); //This requests a star image for the guide view. 32 x 32 pixels + //Note that if it is receiving full size remote images, it should not get the guide star image. + //But if it is not getting the full size images, or if the current camera is not in Ekos, it should get the guide star image + //If we are getting the full size image, we will want to know the lock position for the image that loads in the viewer. + if ( Options::guideSubframeEnabled() || currentCameraIsNotInEkos ) + requestStarImage(32); //This requests a star image for the guide view. 32 x 32 pixels + else + requestLockPosition(); } break; @@ -542,7 +548,9 @@ //Ekos didn't ask for this result? break; - //capture_single_frame + case CAPTURE_SINGLE_FRAME: //capture_single_frame + break; + case CLEAR_CALIBRATION_COMMAND_RECEIVED: //clear_calibration break; @@ -574,7 +582,18 @@ break; //get_cooler_status - //get_current_equipment + case GET_CURRENT_EQUIPMENT: //get_current_equipment + { + QJsonObject equipObject = jsonObj["result"].toObject(); + currentCamera = equipObject["camera"].toObject()["name"].toString(); + currentMount = equipObject["mount"].toObject()["name"].toString(); + currentAuxMount = equipObject["aux_mount"].toObject()["name"].toString(); + + emit guideEquipmentUpdated(); + + break; + } + case DEC_GUIDE_MODE: //get_dec_guide_mode { @@ -606,7 +625,21 @@ emit newLog(logValidExposureTimes); break; } - //get_lock_position + case LOCK_POSITION: //get_lock_position + { + if(jsonObj["result"].toArray().count()==2) + { + double x = jsonObj["result"].toArray().at(0).toDouble(); + double y = jsonObj["result"].toArray().at(1).toDouble(); + QVector3D newStarCenter(x, y, 0); + emit newStarPosition(newStarCenter, true); + + //This is needed so that PHD2 sends the new star pixmap when + //remote images are enabled. + emit newStarPixmap(guideFrame->getTrackingBoxPixmap()); + } + break; + } //get_lock_shift_enabled //get_lock_shift_params //get_paused @@ -636,8 +669,12 @@ case GUIDE_COMMAND_RECEIVED: //guide break; + //guide_pulse - //loop + + case LOOP: //loop + break; + //save_image //set_algo_param @@ -653,7 +690,9 @@ requestExposureTime(); //This will check what it was set to and print a message as to what it is. break; - //set_lock_position + case SET_LOCK_POSITION: //set_lock_position + break; + //set_lock_shift_enabled //set_lock_shift_params @@ -824,6 +863,7 @@ emit newStatus(Ekos::GUIDE_CONNECTED); updateGuideParameters(); requestExposureDurations(); + requestCurrentEquipmentUpdate(); } } @@ -838,6 +878,10 @@ //This section handles the methods/requests sent to PHD2, some are not implemented. //capture_single_frame +void PHD2::captureSingleFrame() +{ + sendPHD2Request("capture_single_frame"); +} //clear_calibration bool PHD2::clearCalibration() @@ -931,6 +975,10 @@ //get_cooler_status //get_current_equipment +void PHD2::requestCurrentEquipmentUpdate() +{ + sendPHD2Request("get_current_equipment"); +} //get_dec_guide_mode void PHD2::checkDEGuideMode() @@ -951,6 +999,10 @@ } //get_lock_position +void PHD2::requestLockPosition() +{ + sendPHD2Request("get_lock_position"); +} //get_lock_shift_enabled //get_lock_shift_params //get_paused @@ -969,9 +1021,6 @@ //get_star_image void PHD2::requestStarImage(int size) { - // if (!Options::guideRemoteImagesEnabled()) - // return; - if (starImageRequested) { if (Options::verboseLogging()) @@ -1027,6 +1076,10 @@ //guide_pulse //loop +void PHD2::loop() +{ + sendPHD2Request("loop"); +} //save_image //set_algo_param @@ -1093,6 +1146,13 @@ } //set_lock_position +void PHD2::setLockPosition(double x,double y) +{ + // Note: false will mean if a guide star is near the coordinates, it will use that. + QJsonArray args; + args << x << y << false; + sendPHD2Request("set_lock_position", args); +} //set_lock_shift_enabled //set_lock_shift_params diff --git a/kstars/ekos/guide/guide.h b/kstars/ekos/guide/guide.h --- a/kstars/ekos/guide/guide.h +++ b/kstars/ekos/guide/guide.h @@ -193,6 +193,7 @@ /** @}*/ void addCamera(ISD::GDInterface *newCCD); + void configurePHD2Camera(); void setTelescope(ISD::GDInterface *newTelescope); void addST4(ISD::ST4 *setST4); void setAO(ISD::ST4 *newAO); @@ -521,7 +522,7 @@ * @param enable True to enable BLOB reception, false to disable BLOB reception * @param name CCD to enable to disable. If empty (default), then action is applied to all CCDs. */ - void setBLOBEnabled(bool enable, const QString &ccd = QString()); + void setExternalGuiderBLOBEnabled(bool enable); void handleManualDither(); @@ -542,6 +543,7 @@ // Devices ISD::CCD *currentCCD { nullptr }; + QString lastPHD2CameraName; //This is for the configure PHD2 camera method. ISD::Telescope *currentTelescope { nullptr }; ISD::ST4 *ST4Driver { nullptr }; ISD::ST4 *AODriver { nullptr }; @@ -630,5 +632,10 @@ bool graphOnLatestPt = true; QUrl guideURLPath; + + //This is for enforcing the PHD2 Star lock when Guide is pressed, + //autostar is not selected, and the user has chosen a star. + //This connection storage is so that the connection can be disconnected after enforcement + QMetaObject::Connection guideConnect; }; } diff --git a/kstars/ekos/guide/guide.cpp b/kstars/ekos/guide/guide.cpp --- a/kstars/ekos/guide/guide.cpp +++ b/kstars/ekos/guide/guide.cpp @@ -115,6 +115,7 @@ connect(opsGuide, &OpsGuide::settingsUpdated, [this]() { onThresholdChanged(Options::guideAlgorithm()); + configurePHD2Camera(); }); page = dialog->addPage(opsGuide, i18n("Guide")); @@ -125,6 +126,10 @@ // Set current guide type setGuiderType(-1); + //This allows the current guideSubframe option to be loaded. + if(guiderType == GUIDE_PHD2) + setExternalGuiderBLOBEnabled(!Options::guideSubframeEnabled()); + //Note: This is to prevent a button from being called the default button //and then executing when the user hits the enter key such as when on a Text Box QList qButtons = findChildren(); @@ -544,29 +549,104 @@ if (CCDs.contains(ccd)) return; - if (guiderType != GUIDE_INTERNAL) + if(guiderType != GUIDE_INTERNAL) { - connect(ccd, &ISD::CCD::newBLOBManager, [ccd](INDI::Property * prop) + connect(ccd, &ISD::CCD::newBLOBManager, [ccd, this](INDI::Property * prop) { if (!strcmp(prop->getName(), "CCD1") || !strcmp(prop->getName(), "CCD2")) - ccd->setBLOBEnabled(Options::guideRemoteImagesEnabled(), prop->getName()); + { + ccd->setBLOBEnabled(false); //This will disable PHD2 external guide frames until it is properly connected. + currentCCD = ccd; + } }); guiderCombo->clear(); guiderCombo->setEnabled(false); if (guiderType == GUIDE_PHD2) guiderCombo->addItem("PHD2"); else guiderCombo->addItem("LinGuider"); - return; } else + { guiderCombo->setEnabled(true); + guiderCombo->addItem(ccd->getDeviceName()); + } CCDs.append(ccd); + checkCCD(); + configurePHD2Camera(); +} + +void Guide::configurePHD2Camera() +{ + //Maybe something like this can be done for Linguider? + //But for now, Linguider doesn't support INDI Cameras + if(guiderType != GUIDE_PHD2) + return; + //This prevents a crash if phd2guider is null + if(!phd2Guider) + return; + //This way it doesn't check if the equipment isn't connected yet. + //It will check again when the equipment is connected. + if(!phd2Guider->isConnected()) + return; + //This way it doesn't check if the equipment List has not been received yet. + //It will ask for the list. When the list is received it will check again. + if(phd2Guider->getCurrentCamera() == "") + { + phd2Guider->requestCurrentEquipmentUpdate(); + return; + } - guiderCombo->addItem(ccd->getDeviceName()); + //this checks to see if a CCD in the list matches the name of PHD2's camera + ISD::CCD *ccdMatch = nullptr; + QString currentPHD2CameraName = "None"; + foreach(ISD::CCD *ccd, CCDs) + { + if(phd2Guider->getCurrentCamera().contains(ccd->getDeviceName())) + { + ccdMatch = ccd; + currentPHD2CameraName = (phd2Guider->getCurrentCamera()); + break; + } + } - checkCCD(); + //If this method gives the same result as last time, no need to update the Camera info again. + //That way the user doesn't see a ton of messages printing about the PHD2 external camera. + //But lets make sure the blob is set correctly every time. + if(lastPHD2CameraName == currentPHD2CameraName) + { + setExternalGuiderBLOBEnabled(!Options::guideSubframeEnabled()); + return; + } + + //This means that a Guide Camera was connected before but it changed. + if(currentCCD) + setExternalGuiderBLOBEnabled(false); + + //Updating the currentCCD + currentCCD = ccdMatch; + + //This updates the last camera name for the next time it is checked. + lastPHD2CameraName = currentPHD2CameraName; + + //This sets a boolean that allows you to tell if the PHD2 camera is in Ekos + phd2Guider->setCurrentCameraIsNotInEkos(currentCCD == nullptr); + + if(phd2Guider->isCurrentCameraNotInEkos()) + { + appendLogText(i18n("PHD2's current camera: %1, is NOT connected to Ekos. The PHD2 Guide Star Image will be received, but the full external guide frames cannot.", phd2Guider->getCurrentCamera())); + subFrameCheck->setEnabled(false); + //We don't want to actually change the user's subFrame Setting for when a camera really is connected, just check the box to tell the user. + disconnect(subFrameCheck, &QCheckBox::toggled, this, &Ekos::Guide::setSubFrameEnabled); + subFrameCheck->setChecked(true); + return; + } + + appendLogText(i18n("PHD2's current camera: %1, IS connected to Ekos. You can select whether to use the full external guide frames or just receive the PHD2 Guide Star Image using the SubFrame checkbox.", phd2Guider->getCurrentCamera())); + subFrameCheck->setEnabled(true); + connect(subFrameCheck, &QCheckBox::toggled, this, &Ekos::Guide::setSubFrameEnabled); + subFrameCheck->setChecked(Options::guideSubframeEnabled()); } void Guide::addGuideHead(ISD::GDInterface *newCCD) @@ -797,7 +877,9 @@ if (targetChip->getFrameType() != FRAME_LIGHT) return; - binningCombo->setEnabled(targetChip->canBin()); + if(guiderType == GUIDE_INTERNAL) + binningCombo->setEnabled(targetChip->canBin()); + int subBinX = 1, subBinY = 1; if (targetChip->canBin()) { @@ -1051,10 +1133,7 @@ { case GUIDE_IDLE: case GUIDE_CONNECTED: - setBLOBEnabled(false); - break; case GUIDE_DISCONNECTED: - setBLOBEnabled(true); break; case GUIDE_CALIBRATING: @@ -1099,14 +1178,16 @@ } else { - if (guiderType == GUIDE_INTERNAL) + if(guiderType != GUIDE_LINGUIDER) { captureB->setEnabled(true); loopB->setEnabled(true); - darkFrameCheck->setEnabled(true); - subFrameCheck->setEnabled(true); autoStarCheck->setEnabled(true); + if(currentCCD) + subFrameCheck->setEnabled(true); } + if (guiderType == GUIDE_INTERNAL) + darkFrameCheck->setEnabled(true); if (calibrationComplete) clearCalibrationB->setEnabled(true); @@ -1448,6 +1529,34 @@ saveSettings(); guider->guide(); + + //If PHD2 gets a Guide command and it is looping, it will accept a lock position + //but if it was not looping it will ignore the lock position and do an auto star automatically + //This is not the default behavior in Ekos if auto star is not selected. + //This gets around that by noting the position of the tracking box, and enforcing it after the state switches to guide. + if(!Options::guideAutoStarEnabled()) + { + if(guiderType == GUIDE_PHD2 && guideView->isTrackingBoxEnabled()) + { + double x = starCenter.x(); + double y = starCenter.y(); + + if(guideView->getImageData() != nullptr) + { + if(guideView->getImageData()->width() > 50) + { + guideConnect = connect(this, &Guide::newStatus, this, [this, x, y](Ekos::GuideState newState) + { + if(newState == GUIDE_GUIDING) + { + phd2Guider->setLockPosition(x,y); + disconnect(guideConnect); + } + }); + } + } + } + } }; if (Options::defaultCaptureCCD() == guiderCombo->currentText()) @@ -1640,6 +1749,8 @@ Options::setGuideSubframeEnabled(enable); if (subFrameCheck->isChecked() != enable) subFrameCheck->setChecked(enable); + if(guiderType == GUIDE_PHD2) + setExternalGuiderBLOBEnabled(!enable); } #if 0 @@ -1713,11 +1824,18 @@ appendLogText(i18n("External guider connected.")); externalConnectB->setEnabled(false); externalDisconnectB->setEnabled(true); - captureB->setEnabled(false); - loopB->setEnabled(false); clearCalibrationB->setEnabled(true); guideB->setEnabled(true); - setBLOBEnabled(false); + + if(guiderType == GUIDE_PHD2) + { + captureB->setEnabled(true); + loopB->setEnabled(true); + autoStarCheck->setEnabled(true); + configurePHD2Camera(); + setExternalGuiderBLOBEnabled(!Options::guideSubframeEnabled()); + boxSizeCombo->setEnabled(true); + } break; case GUIDE_DISCONNECTED: @@ -1729,7 +1847,9 @@ guideB->setEnabled(false); captureB->setEnabled(false); loopB->setEnabled(false); - setBLOBEnabled(true); + autoStarCheck->setEnabled(false); + boxSizeCombo->setEnabled(false); + //setExternalGuiderBLOBEnabled(true); #ifdef Q_OS_OSX repaint(); //This is a band-aid for a bug in QT 5.10.0 #endif @@ -1905,6 +2025,22 @@ void Guide::syncTrackingBoxPosition() { + if(!currentCCD || guiderType == GUIDE_LINGUIDER) + return; + + if(guiderType == GUIDE_PHD2) + { + //This way it won't set the tracking box on the Guide Star Image. + if(guideView->getImageData() != nullptr) + { + if(guideView->getImageData()->width() < 50) + { + guideView->setTrackingBoxEnabled(false); + return; + } + } + } + ISD::CCDChip *targetChip = currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD); Q_ASSERT(targetChip); @@ -2072,14 +2208,7 @@ binningCombo->setEnabled(false); boxSizeCombo->setEnabled(false); filterCombo->setEnabled(false); - - if (Options::guideRemoteImagesEnabled() == false) - { - //guiderCombo->setCurrentIndex(-1); - guiderCombo->setToolTip(i18n("Select a camera to disable remote streaming.")); - } - else - guiderCombo->setEnabled(false); + guiderCombo->setEnabled(false); if (Options::resetGuideCalibration()) appendLogText(i18n("Warning: Reset Guiding Calibration is enabled. It is recommended to turn this option off for PHD2.")); @@ -2112,13 +2241,7 @@ boxSizeCombo->setEnabled(false); filterCombo->setEnabled(false); - if (Options::guideRemoteImagesEnabled() == false) - { - guiderCombo->setCurrentIndex(-1); - guiderCombo->setToolTip(i18n("Select a camera to disable remote streaming.")); - } - else - guiderCombo->setEnabled(false); + guiderCombo->setEnabled(false); updateGuideParams(); @@ -2135,6 +2258,8 @@ connect(guider, &Ekos::GuideInterface::newAxisDelta, this, &Ekos::Guide::setAxisDelta); connect(guider, &Ekos::GuideInterface::newAxisPulse, this, &Ekos::Guide::setAxisPulse); connect(guider, &Ekos::GuideInterface::newAxisSigma, this, &Ekos::Guide::setAxisSigma); + + connect(guider, &Ekos::GuideInterface::guideEquipmentUpdated, this, &Ekos::Guide::configurePHD2Camera); } externalConnectB->setEnabled(false); @@ -2433,6 +2558,16 @@ QVector3D newStarPosition(x, y, -1); setStarPosition(newStarPosition, true); + if(guiderType == GUIDE_PHD2) + { + //The Guide Star Image is 32 pixels across or less, so this guarantees it isn't that. + if(guideView->getImageData() != nullptr) + { + if(guideView->getImageData()->width() > 50) + phd2Guider->setLockPosition(starCenter.x(),starCenter.y()); + } + } + /*if (state == GUIDE_STAR_SELECT) { guider->setStarPosition(newStarPosition); @@ -2445,6 +2580,11 @@ void Guide::setAxisDelta(double ra, double de) { + //If PHD2 starts guiding because somebody pusted the button remotely, we want to set the state to guiding. + //If guide pulses start coming in, it must be guiding. + if(guiderType == GUIDE_PHD2 && state != GUIDE_GUIDING) + setStatus(GUIDE_GUIDING); + // Time since timer started. double key = guideTimer.elapsed() / 1000.0; @@ -2980,32 +3120,34 @@ } } -void Guide::setBLOBEnabled(bool enable, const QString &ccd) +void Guide::setExternalGuiderBLOBEnabled(bool enable) { - // Nothing to do if guider is international or remote images are enabled - if (guiderType == GUIDE_INTERNAL || Options::guideRemoteImagesEnabled()) + // Nothing to do if guider is internal + if (guiderType == GUIDE_INTERNAL) + return; + + if(!currentCCD) return; - // If guider is external and remote images option is disabled AND BLOB is enabled, then we disabled it + currentCCD->setBLOBEnabled(enable); - foreach(ISD::CCD *oneCCD, CCDs) + if(currentCCD->isBLOBEnabled()) { - // If it's not the desired CCD, continue. - if (ccd.isEmpty() == false && QString(oneCCD->getDeviceName()) != ccd) - continue; + if (currentCCD->hasGuideHead() && guiderCombo->currentText().contains("Guider")) + useGuideHead = true; + else + useGuideHead = false; - if (enable == false && oneCCD->isBLOBEnabled()) - { - appendLogText(i18n("Disabling remote image reception from %1", oneCCD->getDeviceName())); - oneCCD->setBLOBEnabled(enable); - } - // Re-enable BLOB reception if it was disabled before when using external guiders - else if (enable && oneCCD->isBLOBEnabled() == false) + ISD::CCDChip *targetChip = + currentCCD->getChip(useGuideHead ? ISD::CCDChip::GUIDE_CCD : ISD::CCDChip::PRIMARY_CCD); + if (targetChip) { - appendLogText(i18n("Enabling remote image reception from %1", oneCCD->getDeviceName())); - oneCCD->setBLOBEnabled(enable); + targetChip->setImageView(guideView, FITS_GUIDE); + targetChip->setCaptureMode(FITS_GUIDE); } + syncCCDInfo(); } + } void Guide::ditherDirectly() @@ -3064,12 +3206,6 @@ { if (guiderType == GUIDE_INTERNAL) Options::setDefaultGuideCCD(ccd); - else if (ccd.isEmpty() == false) - { - QString ccdName = ccd; - ccdName = ccdName.remove(" Guider"); - setBLOBEnabled(Options::guideRemoteImagesEnabled(), ccdName); - } } void Guide::handleManualDither() @@ -3353,13 +3489,6 @@ starCenter = QVector3D(); checkCCD(index); } - else if (index >= 0) - { - // Disable or enable selected CCD based on options - QString ccdName = guiderCombo->currentText().remove(" Guider"); - setBLOBEnabled(Options::guideRemoteImagesEnabled(), ccdName); - checkCCD(index); - } } ); @@ -3369,7 +3498,8 @@ // Dark Frame Check connect(darkFrameCheck, &QCheckBox::toggled, this, &Ekos::Guide::setDarkFrameEnabled); // Subframe check - connect(subFrameCheck, &QCheckBox::toggled, this, &Ekos::Guide::setSubFrameEnabled); + if(guiderType != GUIDE_PHD2) //For PHD2, this is handled in the configurePHD2Camera method + connect(subFrameCheck, &QCheckBox::toggled, this, &Ekos::Guide::setSubFrameEnabled); // ST4 Selection connect(ST4Combo, static_cast(&QComboBox::activated), [&](const QString & text) { @@ -3422,15 +3552,42 @@ state = GUIDE_CAPTURE; emit newStatus(state); - capture(); + if(guiderType == GUIDE_PHD2) + { + configurePHD2Camera(); + if(phd2Guider->isCurrentCameraNotInEkos()) + appendLogText(i18n("The PHD2 camera is not available to Ekos, so you cannot see the captured images. But you will still see the Guide Star Image when you guide.")); + else if(Options::guideSubframeEnabled()) + { + appendLogText(i18n("To receive PHD2 images other than the Guide Star Image, SubFrame must be unchecked. Unchecking it now to enable your image captures. You can re-enable it before Guiding")); + subFrameCheck->setChecked(false); + } + phd2Guider->captureSingleFrame(); + } + else + capture(); }); connect(loopB, &QPushButton::clicked, this, [this]() { state = GUIDE_LOOPING; emit newStatus(state); - capture(); + if(guiderType == GUIDE_PHD2) + { + configurePHD2Camera(); + if(phd2Guider->isCurrentCameraNotInEkos()) + appendLogText(i18n("The PHD2 camera is not available to Ekos, so you cannot see the captured images. But you will still see the Guide Star Image when you guide.")); + else if(Options::guideSubframeEnabled()) + { + appendLogText(i18n("To receive PHD2 images other than the Guide Star Image, SubFrame must be unchecked. Unchecking it now to enable your image captures. You can re-enable it before Guiding")); + subFrameCheck->setChecked(false); + } + phd2Guider->loop(); + stopB->setEnabled(true); + } + else + capture(); }); // Stop @@ -3446,12 +3603,12 @@ // Connect External Guide connect(externalConnectB, &QPushButton::clicked, this, [&]() { - setBLOBEnabled(false); + //setExternalGuiderBLOBEnabled(false); guider->Connect(); }); connect(externalDisconnectB, &QPushButton::clicked, this, [&]() { - setBLOBEnabled(true); + //setExternalGuiderBLOBEnabled(true); guider->Disconnect(); }); diff --git a/kstars/ekos/guide/guide.ui b/kstars/ekos/guide/guide.ui --- a/kstars/ekos/guide/guide.ui +++ b/kstars/ekos/guide/guide.ui @@ -6,7 +6,7 @@ 0 0 - 736 + 782 568 @@ -57,13 +57,33 @@ 3 + + + + Automatically select the calibration star. + + + Auto Star + + + Capture + + + + false + + + Stop + + + @@ -86,13 +106,6 @@ - - - - Loop - - - @@ -160,26 +173,6 @@ - - - - false - - - Stop - - - - - - - <html><head/><body><p>Subframe the image around the guide star. Before checking this option, you must <span style=" font-weight:600;">first</span> capture an image and select a guide star. Uncheck it to take a full frame again.</p></body></html> - - - Subframe - - - @@ -190,13 +183,10 @@ - - - - Automatically select the calibration star. - + + - Auto Star + Loop @@ -222,6 +212,16 @@ + + + + <html><head/><body><p>Subframe the image around the guide star. Or for PHD2, receive the Guide Star Image instead of the full image frame. For the Internal Guider, before checking this option, you must <span style=" font-weight:600;">first</span> capture an image and select a guide star. Uncheck it to take a full frame again.</p></body></html> + + + Subframe + + + diff --git a/kstars/ekos/guide/guideinterface.h b/kstars/ekos/guide/guideinterface.h --- a/kstars/ekos/guide/guideinterface.h +++ b/kstars/ekos/guide/guideinterface.h @@ -69,6 +69,8 @@ void frameCaptureRequested(); + void guideEquipmentUpdated(); + protected: Ekos::GuideState state { GUIDE_IDLE }; double ccdPixelSizeX { 0 }; diff --git a/kstars/ekos/guide/opsguide.cpp b/kstars/ekos/guide/opsguide.cpp --- a/kstars/ekos/guide/opsguide.cpp +++ b/kstars/ekos/guide/opsguide.cpp @@ -32,12 +32,6 @@ //Get a pointer to the KConfigDialog m_ConfigDialog = KConfigDialog::exists("guidesettings"); - connect(kcfg_GuideRemoteImagesEnabled, &QCheckBox::toggled, this, [this] () - { - if (Options::guideRemoteImagesEnabled() != kcfg_GuideRemoteImagesEnabled->isChecked()) - KSNotification::info(i18n("You must restart KStars for this change to take effect.")); - }); - connect(kcfg_DitherNoGuiding, &QCheckBox::toggled, this, [&](bool checked) { if (checked && kcfg_DitherEnabled->isChecked()) { diff --git a/kstars/ekos/guide/opsguide.ui b/kstars/ekos/guide/opsguide.ui --- a/kstars/ekos/guide/opsguide.ui +++ b/kstars/ekos/guide/opsguide.ui @@ -6,8 +6,8 @@ 0 0 - 274 - 455 + 299 + 500 @@ -54,6 +54,49 @@ + + + + 0.500000000000000 + + + 30.000000000000000 + + + 10.000000000000000 + + + + + + + Maximum delta RMS permitted before stopping guide process and searching for new guide stars. + + + Max Delta RMS + + + + + + + <html><head/><body><p>If star tracking is lost due to passing clouds or other reasons, wait this many seconds before giving up.</p></body></html> + + + Lost Star timeout + + + + + + + false + + + Rapid Guide + + + @@ -89,13 +132,10 @@ - - - - <html><head/><body><p>If star tracking is lost due to passing clouds or other reasons, wait this many seconds before giving up.</p></body></html> - + + - Lost Star timeout + seconds @@ -112,66 +152,13 @@ - - - - seconds - - - - - - - Maximum delta RMS permitted before stopping guide process and searching for new guide stars. - - - Max Delta RMS - - - - - - - 0.500000000000000 - - - 30.000000000000000 - - - 10.000000000000000 - - - arcsecs - - - - true - - - For external guiders, enable receiving guide images in Ekos. - - - Receive external guide frames - - - - - - - false - - - Rapid Guide - - - diff --git a/kstars/kstars.kcfg b/kstars/kstars.kcfg --- a/kstars/kstars.kcfg +++ b/kstars/kstars.kcfg @@ -2090,10 +2090,6 @@ false - - - false - 3