bool MICCD::setupParams() { bool sim = isSimulation(); if (sim) { SetCCDParams(4032, 2688, 16, 9, 9); } else { int chipW, chipD, pixelW, pixelD; gxccd_get_integer_parameter(cameraHandle, GIP_CHIP_W, &chipW); gxccd_get_integer_parameter(cameraHandle, GIP_CHIP_D, &chipD); gxccd_get_integer_parameter(cameraHandle, GIP_PIXEL_W, &pixelW); gxccd_get_integer_parameter(cameraHandle, GIP_PIXEL_D, &pixelD); SetCCDParams(chipW, chipD, 16, pixelW / 1000.0, pixelD / 1000.0); } int nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; nbuf += 512; PrimaryCCD.setFrameBufferSize(nbuf); int expTime = 0; gxccd_get_integer_parameter(cameraHandle, GIP_MINIMAL_EXPOSURE, &expTime); minExpTime = expTime / 1000000.0; // convert to seconds PrimaryCCD.setMinMaxStep("CCD_EXPOSURE", "CCD_EXPOSURE_VALUE", minExpTime, 3600, 1, false); gxccd_get_integer_parameter(cameraHandle, GIP_MAX_BINNING_X, &maxBinX); gxccd_get_integer_parameter(cameraHandle, GIP_MAX_BINNING_Y, &maxBinY); if (!sim && hasGain) { float gain = 0; if (gxccd_get_value(cameraHandle, GV_ADC_GAIN, &gain) < 0) { char errorStr[MAX_ERROR_LEN]; gxccd_get_last_error(cameraHandle, errorStr, sizeof(errorStr)); DEBUGF(INDI::Logger::DBG_ERROR, "Getting gain failed: %s.", errorStr); GainN[0].value = 0; GainNP.s = IPS_ALERT; IDSetNumber(&GainNP, NULL); return false; } else { GainN[0].value = gain; GainNP.s = IPS_OK; IDSetNumber(&GainNP, NULL); } } return true; }
bool GPhotoCCD::updateProperties() { INDI::CCD::updateProperties(); if (isConnected()) { if (mIsoSP.nsp > 0) defineSwitch(&mIsoSP); if (mFormatSP.nsp > 0) defineSwitch(&mFormatSP); defineSwitch(&transferFormatSP); defineSwitch(&livePreviewSP); defineSwitch(&autoFocusSP); defineSwitch(&FocusMotionSP); defineNumber(&FocusSpeedNP); defineNumber(&FocusTimerNP); imageBP=getBLOB("CCD1"); imageB=imageBP->bp; // Dummy values until first capture is done SetCCDParams(1280, 1024, 8, 5.4, 5.4); if (sim == false) { ShowExtendedOptions(); DEBUG(INDI::Logger::DBG_SESSION, "Please update the camera pixel size in the Image Info section. The camera resolution will be updated after the first exposure is complete."); // Only show mirror lock if the camera is canon ITextVectorProperty *modelTP = getText("model"); if (modelTP && !strcmp(modelTP->label, "model") && strstr(modelTP->tp[0].text, "Canon")) defineNumber(&mMirrorLockNP); } //timerID = SetTimer(POLLMS); } else { if (mIsoSP.nsp > 0) deleteProperty(mIsoSP.name); if (mFormatSP.nsp > 0) deleteProperty(mFormatSP.name); deleteProperty(mMirrorLockNP.name); deleteProperty(livePreviewSP.name); deleteProperty(autoFocusSP.name); deleteProperty(transferFormatSP.name); deleteProperty(FocusMotionSP.name); deleteProperty(FocusSpeedNP.name); deleteProperty(FocusTimerNP.name); HideExtendedOptions(); //rmTimer(timerID); } return true; }
/******************************************************************************* ** Setting up CCD parameters *******************************************************************************/ void DSICCD::setupParams() { SetCCDParams(dsi->getImageWidth(), dsi->getImageHeight(), dsi->getReadBpp() * 8, dsi->getPixelSizeX(), dsi->getPixelSizeY()); /* calculate how much memory we need for the primary CCD buffer */ PrimaryCCD.setFrameBufferSize(PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP()/8); }
/************************************************************************************** ** Setting up CCD parameters ***************************************************************************************/ void FFMVCCD::setupParams() { // The FireFly MV has a Micron MT9V022 CMOS sensor SetCCDParams(640, 480, 16, 6.0, 6.0); // Let's calculate how much memory we need for the primary CCD buffer int nbuf; nbuf=PrimaryCCD.getXRes()*PrimaryCCD.getYRes() * PrimaryCCD.getBPP()/8; PrimaryCCD.setFrameBufferSize(nbuf); }
/************************************************************************************** ** Setting up CCD parameters ***************************************************************************************/ void INovaCCD::setupParams() { int bpp = iNovaSDK_GetDataWide() > 0 ? 16 : 8; SetCCDParams(iNovaSDK_GetImageWidth(), iNovaSDK_GetImageHeight(), bpp, iNovaSDK_GetPixelSizeX(), iNovaSDK_GetPixelSizeY()); // Let's calculate how much memory we need for the primary CCD buffer int nbuf; nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; nbuf += 512; // leave a little extra at the end PrimaryCCD.setFrameBufferSize(nbuf); }
bool QHYCCD::setupParams() { uint32_t nbuf,ret,imagew,imageh,bpp; double chipw,chiph,pixelw,pixelh; if (sim) { chipw=imagew=1280; chiph=imageh=1024; pixelh = pixelw = 5.4; bpp=8; } else { ret = GetQHYCCDChipInfo(camhandle,&chipw,&chiph,&imagew,&imageh,&pixelw,&pixelh,&bpp); /* JM: We need GetQHYCCDErrorString(ret) to get the string description of the error, please implement this in the SDK */ if (ret != QHYCCD_SUCCESS) { DEBUGF(INDI::Logger::DBG_ERROR, "Error: GetQHYCCDChipInfo() (%d)", ret); return false; } DEBUGF(INDI::Logger::DBG_DEBUG, "GetQHYCCDChipInfo: chipW :%g chipH: %g imageW: %g imageH: %g pixelW: %g pixelH: %g bbp %g", chipw,chiph,imagew,imageh,pixelw,pixelh,bpp); camroix = 0; camroiy = 0; camroiwidth = imagew; camroiheight = imageh; } SetCCDParams(imagew,imageh,bpp,pixelw,pixelh); nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; PrimaryCCD.setFrameBufferSize(nbuf); #ifndef OSX_EMBEDED_MODE streamer->setPixelFormat(V4L2_PIX_FMT_GREY); streamer->setRecorderSize(imagew,imageh); #endif return true; }
bool FishCampCCD::initProperties() { // Init parent properties first INDI::CCD::initProperties(); IUFillNumber(&GainN[0], "Range", "", "%g", 1, 15, 1., 4.); IUFillNumberVector(&GainNP, GainN, 1, getDeviceName(), "Gain", "", MAIN_CONTROL_TAB, IP_RW, 60, IPS_IDLE); IUFillNumber(&CoolerN[0], "Power %", "", "%g", 1, 100, 0, 0.0); IUFillNumberVector(&CoolerNP, CoolerN, 1, getDeviceName(), "Cooler", "", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); char *strBuf = new char[MAXINDINAME]; IUFillText(&CamInfoT[0], "Name", "", name); IUFillText(&CamInfoT[1], "Serial #", "", (char *)&camInfo.camSerialStr); snprintf(strBuf, MAXINDINAME, "%d", camInfo.boardVersion); IUFillText(&CamInfoT[2], "Board version", "", strBuf); snprintf(strBuf, MAXINDINAME, "%d", camInfo.boardRevision); IUFillText(&CamInfoT[3], "Board revision", "", strBuf); snprintf(strBuf, MAXINDINAME, "%d", camInfo.fpgaVersion); IUFillText(&CamInfoT[4], "FPGA version", "", strBuf); snprintf(strBuf, MAXINDINAME, "%d", camInfo.fpgaRevision); IUFillText(&CamInfoT[5], "FPGA revision", "", strBuf); IUFillTextVector(&CamInfoTP, CamInfoT, 6, getDeviceName(), "Camera Info", "", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE); SetCCDParams(camInfo.width, camInfo.height, 16, camInfo.pixelWidth / 10.0, camInfo.pixelHeight / 10.0); int nbuf; nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; // this is pixel cameraCount nbuf += 512; // leave a little extra at the end PrimaryCCD.setFrameBufferSize(nbuf); SetCCDCapability(CCD_CAN_ABORT | CCD_CAN_SUBFRAME | CCD_HAS_COOLER | CCD_HAS_ST4_PORT); delete[] strBuf; return true; }
bool CCDSim::SetupParms() { int nbuf; SetCCDParams(SimulatorSettingsN[0].value,SimulatorSettingsN[1].value,16,SimulatorSettingsN[2].value,SimulatorSettingsN[3].value); // Kwiq maxnoise=SimulatorSettingsN[8].value; skyglow=SimulatorSettingsN[9].value; maxval=SimulatorSettingsN[4].value; bias=SimulatorSettingsN[5].value; limitingmag=SimulatorSettingsN[7].value; saturationmag=SimulatorSettingsN[6].value; OAGoffset=SimulatorSettingsN[10].value; // An oag is offset this much from center of scope position (arcminutes); nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP()/8; nbuf += 512; PrimaryCCD.setFrameBufferSize(nbuf); GetFilterNames(FILTER_TAB); return true; }
bool ASICCD::setupParams() { ASI_ERROR_CODE errCode = ASI_SUCCESS; int piNumberOfControls = 0; errCode = ASIGetNumOfControls(m_camInfo->CameraID, &piNumberOfControls); if (errCode != ASI_SUCCESS) DEBUGF(INDI::Logger::DBG_DEBUG, "ASIGetNumOfControls error (%d)", errCode); if (piNumberOfControls > 0) { if (ControlNP.nnp > 0) free(ControlN); if (ControlSP.nsp > 0) free(ControlS); createControls(piNumberOfControls); } // Set minimum ASI_BANDWIDTHOVERLOAD on ARM #ifdef LOW_USB_BANDWIDTH ASI_CONTROL_CAPS pCtrlCaps; for(int j = 0; j < piNumberOfControls; j++) { ASIGetControlCaps(m_camInfo->CameraID, j, &pCtrlCaps); if (pCtrlCaps.ControlType == ASI_BANDWIDTHOVERLOAD) { DEBUGF(INDI::Logger::DBG_DEBUG, "setupParams->set USB %d", pCtrlCaps.MinValue); ASISetControlValue(m_camInfo->CameraID, ASI_BANDWIDTHOVERLOAD, pCtrlCaps.MinValue, ASI_FALSE); break; } } #endif // Get Image Format int w=0, h=0, bin=0; ASI_IMG_TYPE imgType; ASIGetROIFormat(m_camInfo->CameraID, &w, &h, &bin, &imgType); DEBUGF(INDI::Logger::DBG_DEBUG, "CCD ID: %d Width: %d Height: %d Binning: %dx%d Image Type: %d", m_camInfo->CameraID, w, h, bin, bin, imgType); // Get video format and bit depth int bit_depth = 8; switch (imgType) { case ASI_IMG_RAW16: bit_depth = 16; default: break; } if (VideoFormatSP.nsp > 0) free(VideoFormatS); VideoFormatS = NULL; int nVideoFormats = 0; for (int i=0; i < 8; i++) { if (m_camInfo->SupportedVideoFormat[i] == ASI_IMG_END) break; nVideoFormats++; VideoFormatS = VideoFormatS == NULL ? (ISwitch *) malloc(sizeof(ISwitch)) : (ISwitch *) realloc(VideoFormatS, nVideoFormats * sizeof(ISwitch)); ISwitch *oneVF = VideoFormatS + (nVideoFormats-1); switch (m_camInfo->SupportedVideoFormat[i]) { case ASI_IMG_RAW8: IUFillSwitch(oneVF, "ASI_IMG_RAW8", "Raw 8 bit", (imgType == ASI_IMG_RAW8) ? ISS_ON : ISS_OFF); DEBUG(INDI::Logger::DBG_DEBUG, "Supported Video Format: ASI_IMG_RAW8"); break; case ASI_IMG_RGB24: IUFillSwitch(oneVF, "ASI_IMG_RGB24", "RGB 24", (imgType == ASI_IMG_RGB24) ? ISS_ON : ISS_OFF); DEBUG(INDI::Logger::DBG_DEBUG, "Supported Video Format: ASI_IMG_RGB24"); break; case ASI_IMG_RAW16: IUFillSwitch(oneVF, "ASI_IMG_RAW16", "Raw 16 bit", (imgType == ASI_IMG_RAW16) ? ISS_ON : ISS_OFF); DEBUG(INDI::Logger::DBG_DEBUG, "Supported Video Format: ASI_IMG_RAW16"); break; case ASI_IMG_Y8: IUFillSwitch(oneVF, "ASI_IMG_Y8", "Luma", (imgType == ASI_IMG_Y8) ? ISS_ON : ISS_OFF); DEBUG(INDI::Logger::DBG_DEBUG, "Supported Video Format: ASI_IMG_Y8"); break; default: DEBUGF(INDI::Logger::DBG_DEBUG, "Unknown video format (%d)", m_camInfo->SupportedVideoFormat[i]); break; } oneVF->aux = (void *) &m_camInfo->SupportedVideoFormat[i]; } VideoFormatSP.nsp = nVideoFormats; VideoFormatSP.sp = VideoFormatS; float x_pixel_size, y_pixel_size; int x_1, y_1, x_2, y_2; x_pixel_size = m_camInfo->PixelSize; y_pixel_size = m_camInfo->PixelSize; x_1 = y_1 = 0; x_2 = m_camInfo->MaxWidth; y_2 = m_camInfo->MaxHeight; SetCCDParams(x_2 - x_1, y_2 - y_1, bit_depth, x_pixel_size, y_pixel_size); // Let's calculate required buffer int nbuf; nbuf = PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8; // this is pixel cameraCount //nbuf += 512; // leave a little extra at the end PrimaryCCD.setFrameBufferSize(nbuf); //if (HasCooler()) //{ long pValue = 0; ASI_BOOL isAuto= ASI_FALSE; if ( (errCode = ASIGetControlValue(m_camInfo->CameraID, ASI_TEMPERATURE, &pValue, &isAuto)) != ASI_SUCCESS) DEBUGF(INDI::Logger::DBG_DEBUG, "ASIGetControlValue temperature error (%d)", errCode); TemperatureN[0].value = pValue / 10.0; DEBUGF(INDI::Logger::DBG_SESSION, "The CCD Temperature is %f", TemperatureN[0].value); IDSetNumber(&TemperatureNP, NULL); //} ASIStopVideoCapture(m_camInfo->CameraID); DEBUGF(INDI::Logger::DBG_DEBUG, "setupParams ASISetROIFormat (%dx%d, bin %d, type %d)", m_camInfo->MaxWidth, m_camInfo->MaxHeight, 1, imgType); ASISetROIFormat(m_camInfo->CameraID, m_camInfo->MaxWidth, m_camInfo->MaxHeight, 1, imgType); #if !defined(OSX_EMBEDED_MODE) && !defined(__CYGWIN__) updateRecorderFormat(); streamer->setRecorderSize(w,h); #endif return true; }
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; }
bool ATIKCCD::setupParams() { ARTEMISPROPERTIES pProp; int rc = ArtemisProperties(hCam, &pProp); if (rc != ARTEMIS_OK) { LOGF_ERROR("Failed to inquire camera properties (%d)", rc); return false; } // Camera & Pixel properties // FIXME is it always 16bit depth? SetCCDParams(pProp.nPixelsX, pProp.nPixelsY, 16, pProp.PixelMicronsX, pProp.PixelMicronsY); // Set frame buffer size PrimaryCCD.setFrameBufferSize(PrimaryCCD.getXRes() * PrimaryCCD.getYRes() * PrimaryCCD.getBPP() / 8, false); m_CameraFlags = pProp.cameraflags; LOGF_DEBUG("Camera flags: %d", m_CameraFlags); int binX = 1, binY = 1; rc = ArtemisGetMaxBin(hCam, &binX, &binY); if (rc != ARTEMIS_OK) { LOGF_ERROR("Failed to inquire camera max binning (%d)", rc); } PrimaryCCD.setMinMaxStep("CCD_EXPOSURE", "CCD_EXPOSURE_VALUE", 0.001, 3600, 1, false); PrimaryCCD.setMinMaxStep("CCD_BINNING", "HOR_BIN", 1, binX, 1, false); PrimaryCCD.setMinMaxStep("CCD_BINNING", "VER_BIN", 1, binY, 1, false); IUSaveText(&VersionInfoS[VERSION_FIRMWARE], std::to_string(pProp.Protocol).c_str()); LOGF_INFO("Detected camera %s %s with firmware %s", pProp.Manufacturer, pProp.Description, std::to_string(pProp.Protocol).c_str()); uint32_t cap = 0; // All Atik cameras can abort and subframe cap = CCD_CAN_ABORT | CCD_CAN_SUBFRAME; // Can we bin? if (binX > 1) { cap |= CCD_CAN_BIN; LOG_DEBUG("Camera can bin."); } // Do we have color or mono camera? ARTEMISCOLOURTYPE colorType; rc = ArtemisColourProperties(hCam, &colorType, &normalOffsetX, &normalOffsetY, &previewOffsetX, &previewOffsetY); if (rc != ARTEMIS_OK) { LOGF_ERROR("Failed to inquire camera color (%d). Assuming Mono.", rc); } if (colorType == ARTEMIS_COLOUR_RGGB) { cap |= CCD_HAS_BAYER; IUSaveText(&BayerT[0], std::to_string(normalOffsetX).c_str()); IUSaveText(&BayerT[1], std::to_string(normalOffsetY).c_str()); } LOGF_DEBUG("Camera is %s.", colorType == ARTEMIS_COLOUR_RGGB ? "Color" : "Mono"); // Do we have temperature? rc = ArtemisTemperatureSensorInfo(hCam, 0, &m_TemperatureSensorsCount); LOGF_DEBUG("Camera has %d temperature sensor(s).", m_TemperatureSensorsCount); if (m_TemperatureSensorsCount > 0) { // Do we have cooler control? int flags, level, minlvl, maxlvl, setpoint; rc = ArtemisCoolingInfo(hCam, &flags, &level, &minlvl, &maxlvl, &setpoint); if (flags & 0x1) { LOG_DEBUG("Camera supports cooling control."); cap |= CCD_HAS_COOLER; } genTimerID = SetTimer(TEMP_TIMER_MS); } // Do we have mechanical shutter? if (m_CameraFlags & ARTEMIS_PROPERTIES_CAMERAFLAGS_HAS_SHUTTER) { LOG_DEBUG("Camera has mechanical shutter."); cap |= CCD_HAS_SHUTTER; } // Do we have guide port? if (m_CameraFlags & ARTEMIS_PROPERTIES_CAMERAFLAGS_HAS_GUIDE_PORT) { LOG_DEBUG("Camera has guide port."); cap |= CCD_HAS_ST4_PORT; } // Done with the capabilities! SetCCDCapability(cap); // Check if camra has internal filter wheel if (m_CameraFlags & ARTEMIS_PROPERTIES_CAMERAFLAGS_HAS_FILTERWHEEL) { int numFilters, moving, currentPos, targetPos; rc = ArtemisFilterWheelInfo(hCam, &numFilters, &moving, ¤tPos, &targetPos); if (rc != ARTEMIS_OK) { LOGF_ERROR("Failed to inquire internal filter wheel info (%d). Filter wheel functions are disabled.", rc); } else { setDriverInterface(getDriverInterface() | FILTER_INTERFACE); FilterSlotN[0].min = 1; FilterSlotN[0].max = numFilters; LOGF_INFO("Detected %d-position internal filter wheel.", numFilters); } } // Check if we have Horizon camera m_isHorizon = ArtemisHasCameraSpecificOption(hCam, 1); if (m_isHorizon) { uint8_t data[2] = {0}; int len = 0, index = 0; ArtemisCameraSpecificOptionGetData(hCam, ID_AtikHorizonGOPresetMode, data, 2, &len); index = *(reinterpret_cast<uint16_t*>(&data)); LOGF_DEBUG("Horizon current GO mode: data[0] %d data[1] %d index %d", data[0], data[1], index); IUResetSwitch(&ControlPresetsSP); ControlPresetsS[index].s = ISS_ON; // Get Gain & Offset valuse ArtemisCameraSpecificOptionGetData(hCam, ID_AtikHorizonGOCustomGain, data, 2, &len); index = *(reinterpret_cast<uint16_t*>(&data)); LOGF_DEBUG("Horizon current gain: data[0] %d data[1] %d value %d", data[0], data[1], index); ArtemisCameraSpecificOptionGetData(hCam, ID_AtikHorizonGOCustomOffset, data, 2, &len); index = *(reinterpret_cast<uint16_t*>(&data)); LOGF_DEBUG("Horizon current offset: data[0] %d data[1] %d value %d", data[0], data[1], index); } // Create imaging thread threadRequest = StateIdle; threadState = StateNone; int stat = pthread_create(&imagingThread, nullptr, &imagingHelper, this); if (stat != 0) { LOGF_ERROR("Error creating imaging thread (%d)", stat); return false; } pthread_mutex_lock(&condMutex); while (threadState == StateNone) { pthread_cond_wait(&cv, &condMutex); } pthread_mutex_unlock(&condMutex); return true; }