//Autofocus manages the TSX functions to refocus the camera // every change of 1 degree in temperature. //The first fime autofocus is called, the telescope is slewed to // a position with Az = 90, Alt = 80. Then @Focus2 is called with // TSX providing the star to use. the temperature at that time is recorded. //Subsequent calls to autofocus check to see if the current focuser temperature // is more than a degree celsius different from the last @autofocus2 time. // if so, @autofocus2 is called again, although the telescope is not slewed. And so on. public static string Check() { //check to see if current temperature is a degree different from last temperature // If so, then set up and run @focus2 //AtFocus2 chooses to use a 15 degree x 15 degree field of view to choose a focus star // If the current position is close to the meridian then a focus star on the other // side of the meridian can be choosen and the mount will flip trying to get to it // and, if using a dome, the slew does not wait for the dome slit to catch up (CLS flaw) // so not only will an exception be thrown (Dome command in progress Error 125) the first image // will be crap and the focus fail (as of DB 11360). So, this method will point the mount to a // altitude that is no more than 80 degrees at the same azimuth of the current position in order // to avoid a flip and subsequent bullshit happening ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.Connect(); double currentTemp = tsxc.focTemperature; if (Math.Abs(currentTemp - afLastTemp) > 1) { //Going to have to refocus. //Move to altitude away from meridian, if need be sky6RASCOMTele tsxt = new sky6RASCOMTele(); tsxt.GetAzAlt(); double tAlt = tsxt.dAlt; if (tAlt > 80) { double tAz = tsxt.dAz; tAlt = 80.0; //turn off tracking to avoid dome error //DeviceControl dctl = new DeviceControl(); //dctl.DomeTrackingOff(); tsxt.SlewToAzAlt(tAz, tAlt, "AtFocus2ReadyPosition"); //dctl.DomeTrackingOn(); } //reset last temp afLastTemp = currentTemp; int syncSave = tsxc.Asynchronous; tsxc.Asynchronous = 0; try { int focStat = tsxc.AtFocus2(); } catch (Exception e) { tsxc.Asynchronous = syncSave; return("Focus Check: " + e.Message); } return("Focus Check: Focus successful"); } return("Focus Check: Temperature change less than 1 degree"); }
private void ImageAbort_Click(object sender, EventArgs e) { //Stop the imaging, clean up form ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.Abort(); ImageButton.BackColor = Color.LightGreen; ImageAbort.Visible = false; RepsBox.Value = 1; return; }
/// ******************************************************************************** private void TargetLoop() { string szPathToMapFile = "C:\\Users\\Rick\\Documents\\Software Bisque\\TheSkyX Professional Edition\\Exported Data\\map.txt"; ///Set the exposure time for the image double dExposure = 1.0; string LineFromFile; double dAz; double dAlt; //Connect to TSX TheSky and Uility methods sky6Utils tsx_util = new sky6Utils(); sky6RASCOMTheSky tsx_sky = new sky6RASCOMTheSky(); sky6RASCOMTele tsx_tele = new sky6RASCOMTele(); ccdsoftCamera tsx_cam = new ccdsoftCamera(); ///Open the observing list export file for targets StreamReader MyFile = File.OpenText(szPathToMapFile); ///Stream object for Export Data text file ///Get the first line -- headers ///Exit if the file is empty if (MyFile.EndOfStream == true) { return; } ; LineFromFile = MyFile.ReadLine(); int iRAindex = LineFromFile.IndexOf("RA"); int iDecindex = LineFromFile.IndexOf("Dec"); while (MyFile.EndOfStream == false) { LineFromFile = MyFile.ReadLine(); MessageBox.Show("RA: " + LineFromFile.Substring(iRAindex, 13) + " Dec: " + LineFromFile.Substring(iDecindex, 13)); string sname = LineFromFile.Substring((LineFromFile.Length - 12), 12); tsx_util.ConvertStringToRA(LineFromFile.Substring(iRAindex, 13)); dAz = tsx_util.dOut0; tsx_util.ConvertStringToDec(LineFromFile.Substring(iDecindex, 13)); dAlt = tsx_util.dOut0; ///Slew to object tsx_tele.SlewToAzAlt(dAz, dAlt, sname); ///Set exposure time and try { for image, exit if error tsx_cam.ExposureTime = dExposure; tsx_cam.TakeImage(); ///Add to T-point Model tsx_sky.AutoMap(); } ; //Loop }
private bool OptimizeExposure(double maxExposure) { //Subframe size const int subFrameSize = 192; //Subframe the center in order to get rid of any brighter outliers const int testExposure = 10; const double minExposure = 0.1; ccdsoftImage tsxi = new ccdsoftImage(); tsxi.AttachToActive(); //We should have a CLS image handy double xcenter = tsxi.WidthInPixels / 2; double ycenter = tsxi.HeightInPixels / 2; //Set up 64 pixel square subframe int subTop = (int)ycenter - subFrameSize / 2; //Y is top down int subBottom = (int)ycenter + subFrameSize / 2; //Y is top down int subRight = (int)xcenter + subFrameSize / 2; int subLeft = (int)xcenter - subFrameSize / 2; Configuration cfg = new Configuration(); int ADUMax = Convert.ToInt32(cfg.ADUMax); ccdsoftCamera tsx_cc = new ccdsoftCamera { AutoSaveOn = 0, //Autosave Off FilterIndexZeroBased = freshImageFilter, ExposureTime = testExposure, Subframe = 1, SubframeTop = subTop, SubframeBottom = subBottom, SubframeLeft = subLeft, SubframeRight = subRight, Frame = ccdsoftImageFrame.cdLight, ImageReduction = ccdsoftImageReduction.cdAutoDark, Asynchronous = 0 //Asynchronous off for this short shot }; do { tsx_cc.TakeImage(); double maxPixel = tsx_cc.MaximumPixel; double correctExposure = (ADUMax / maxPixel) * tsx_cc.ExposureTime; if (correctExposure > maxExposure) { correctExposure = maxExposure; } freshImageExposure = correctExposure; if (maxPixel > ADUMax) { tsx_cc.ExposureTime = freshImageExposure; } } while (tsx_cc.MaximumPixel > ADUMax && freshImageExposure > minExposure); return(true); }
//Take an image via TSX. Set the autosave path to the FreshImage path; // Set exposureTime, Light Frame, AutoDark, No Autosave, Asynchronous // then TakeImage // Wait for completion status, then return // // Removed subframe setting on request for cameras with long download times private void ShootGalaxy() { Configuration sscf = new Configuration(); ccdsoftImage tsx_im = new ccdsoftImage { Path = sscf.FreshImagePath }; ccdsoftCamera tsx_cc = new ccdsoftCamera { AutoSaveOn = 0, //Autosave Off FilterIndexZeroBased = Convert.ToInt32(sscf.Filter), ExposureTime = Convert.ToDouble(sscf.Exposure), //Subframe = 0, Frame = ccdsoftImageFrame.cdLight, //ImageReduction = ccdsoftImageReduction.cdAutoDark, Asynchronous = 1 //Asynchronous on }; switch (sscf.CalibrationType) { case "None": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdNone; break; } case "Auto": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; break; } case "Full": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdBiasDarkFlat; break; } } LogEntry("Imaging target for " + sscf.Exposure + " secs"); tsx_cc.TakeImage(); //Wait for completion while (tsx_cc.State != ccdsoftCameraState.cdStateNone) { System.Threading.Thread.Sleep(1000); System.Windows.Forms.Application.DoEvents(); } tsx_im.AttachToActiveImager(); tsx_im.Save(); freshImagePath = sscf.FreshImagePath; LogEntry("Imaging Complete"); return; }
public static void RunTempComp() { //Enable Temperature compensation with current data to mode A (for Optec) // lg = FormHumason.LogReport; ccdsoftCamera tsxc = new ccdsoftCamera { focTemperatureCompensationMode = ccdsoftfocTempCompMode.cdfocTempCompMode_A }; //lg.LogIt("Focuser Temperature Compensation turned on"); return; }
public void SetCameraTemperature(double settemp) { //Method for setting TSX camera temp ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.TemperatureSetPoint = settemp; tsxc.RegulateTemperature = 1; while (!TTUtility.CloseEnough(tsxc.Temperature, settemp, 90)) { System.Threading.Thread.Sleep(1); } ; return; }
public static string[] FilterNameList() { //Figure out the filter mapping //Find the filter name for the filter filter Number ccdsoftCamera tsxc = new ccdsoftCamera(); int filterCount = tsxc.lNumberFilters; string[] TSXFilterList = new string[filterCount]; for (int f = 0; f < filterCount; f++) { TSXFilterList[f] = (tsxc.szFilterName(f)); } return(TSXFilterList); }
//SexTractor-based method for getting the ADU of the brightest star in an image public static double GuiderStarADUSex(double exposure, bool AOEnabled) { //Determines the ADU for the X/Y centroid of the maximum FWHM star in a subframe // //Take a full frame image on the guider using TSX guide star coordinates and trackbox size ccdsoftCamera tsxg = new ccdsoftCamera { Autoguider = 1, Frame = ccdsoftImageFrame.cdLight, Delay = 0, Asynchronous = 0, AutoSaveOn = 1, AutoguiderExposureTime = exposure, ExposureTime = exposure }; int tstat = tsxg.TakeImage(); if (tstat != 0) { return(0); } //Next step is to generate the collection of stars in the frame SexTractor sEx = new SexTractor(); sEx.SourceExtractGuider(); List <double> FWHMlist = sEx.GetSourceExtractionList(SexTractor.SourceExtractionType.sexFWHM); List <double> CenterX = sEx.GetSourceExtractionList(SexTractor.SourceExtractionType.sexX); List <double> CenterY = sEx.GetSourceExtractionList(SexTractor.SourceExtractionType.sexY); int iMax = sEx.GetListLargest(FWHMlist); double maxStarADU = 0; try { maxStarADU = sEx.GetPixelADU((int)CenterX[iMax], (int)CenterY[iMax]); } catch (Exception ex) { maxStarADU = 0; } tstat = tsxg.TakeImage(); if (maxStarADU == 0) { maxStarADU = tsxg.MaximumPixel; } return(maxStarADU); }
public static int MoveTo(double position) { int movestat; ccdsoftCamera tsxc = new ccdsoftCamera(); if (position < tsxc.focPosition) { movestat = tsxc.focMoveIn((int)(tsxc.focPosition - position)); } else { movestat = tsxc.focMoveOut((int)(position - tsxc.focPosition)); } return(movestat); }
private double PlateSolve() { //runs an image link on the current location to get PA data //assume camera, mount etc are connected and properly configured. ccdsoftCamera tsxcc = new ccdsoftCamera { Autoguider = 0, Frame = ccdsoftImageFrame.cdLight, ExposureTime = 10, Delay = 0, Asynchronous = 0, AutoSaveOn = 1, Subframe = 0 }; try { tsxcc.TakeImage(); } catch (Exception ex) { WriteLog(ex.Message); return(0); } ccdsoftImage tsxi = new ccdsoftImage(); ImageLink tsxil = new ImageLink { pathToFITS = tsxcc.LastImageFileName, scale = 1.70 }; try { tsxil.execute(); } catch (Exception ex) { return(0); } ImageLinkResults tsxir = new ImageLinkResults(); double iPA = tsxir.imagePositionAngle; //Check for image link success, return 0 if not. if (tsxir.succeeded == 1) { return(iPA); } else { return(0); } }
public void Shoot(string gName, double expTime) { //Take a fresh image at 600 seconds //That will be placed in the Configuration sscfg = new Configuration(); ccdsoftImage tsx_im = new ccdsoftImage(); ccdsoftCamera tsx_cc = new ccdsoftCamera(); tsx_im.Path = FollowUpPath + "\\" + gName + ".fit"; tsx_cc.AutoSaveOn = 0; //Autosave Off //No filter change tsx_cc.ExposureTime = expTime; tsx_cc.Frame = ccdsoftImageFrame.cdLight; tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; switch (sscfg.CalibrationType) { case "None": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdNone; break; } case "Auto": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; break; } case "Full": { tsx_cc.ImageReduction = ccdsoftImageReduction.cdBiasDarkFlat; break; } } tsx_cc.Asynchronous = 0; //Asynchronous on tsx_cc.TakeImage(); //Wait for completion while (tsx_cc.State != ccdsoftCameraState.cdStateNone) { System.Threading.Thread.Sleep(1000); System.Windows.Forms.Application.DoEvents(); } tsx_im.AttachToActiveImager(); tsx_im.Save(); }
public bool CLSToTarget(SpeedVector sv) { int clsStatus = 123; sky6RASCOMTele tsxmt = new sky6RASCOMTele(); ClosedLoopSlew tsx_cl = new ClosedLoopSlew(); sky6StarChart tsxsc = new sky6StarChart(); //Clear any image reduction, otherwise full reduction might cause a problem ccdsoftCamera tsxcam = new ccdsoftCamera() { ImageReduction = ccdsoftImageReduction.cdNone, Asynchronous = 1 //make sure nothing else happens while setting this up }; //Abort any ongoing imaging tsxcam.Abort(); double tgtRAH = Transform.DegreesToHours(sv.RA_Degrees - RA_CorrectionD); double tgtDecD = sv.Dec_Degrees - Dec_CorrectionD; tsxsc.Find(tgtRAH.ToString() + ", " + tgtDecD.ToString()); tsxmt.Connect(); try { tsxmt.SlewToRaDec(tgtRAH, tgtDecD, TgtName); } catch (Exception ex) { MessageBox.Show("Slew to target failed: " + ex.Message); return(false); } //********** CLS AVOIDANCE CODE FOR SIMULATOR DEBUGGING PURPOSES //tsxsc.Find(TgtName); //return true; //********************* try { clsStatus = tsx_cl.exec(); } catch (Exception ex) { tsxsc.Find(TgtName); return(false); } tsxsc.Find(TgtName); return(true); }
/* * Note: Calibration folders are expected to have the format * * B<*>_T<*>_E<*>_F<*> * * Object decription * * Opening a reduction object produces list of calibration folders * that can be parsed for specific temp, filter and exposure */ public Reduction() { ccdsoftCamera tsxc = new ccdsoftCamera(); //Figure out the filter mapping //Find the filter name for the filter filter Number FilterList = Filters.FilterNameList(); int reductionGroupCount = tsxc.ReductionGroupCount; for (int g = 0; g < reductionGroupCount; g++) { string parseName = tsxc.ReductionGroupFromIndex(g); if (parseName.Contains("Group_")) { ReductionLibrary reductionLib = new ReductionLibrary(parseName); LibraryList.Add(reductionLib); } } }
public static List <string> FilterWheelList() { ccdsoftCamera tsxc = new ccdsoftCamera(); //Connect the camera, if fails, then just return after clean up try { tsxc.Connect(); } catch { return(null); } List <string> tfwList = new List <string>(); for (int filterIndex = 0; filterIndex < tsxc.lNumberFilters; filterIndex++) { tfwList.Add(tsxc.szFilterName(filterIndex)); } return(tfwList); }
public static string PresetFocus() { //Sets the focuser to the position set by the StepsPerDegree and StepAtZero (slope and intercept) // as accumulated for the focuser. If StepsPerDegree is zero, then no movement is made Configuration cfg = new Configuration(); ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.Connect(); double currentTemp = tsxc.focTemperature; int currentPosition = tsxc.focPosition; double stepsPerDegree = Convert.ToDouble(cfg.StepsPerDegree); double positionAtZero = Convert.ToDouble(cfg.PositionAtZero); string logUpdate; if (stepsPerDegree != 0.0) { int newPosition = (int)(currentTemp * stepsPerDegree + positionAtZero); int move = (newPosition - currentPosition); logUpdate = "Moving Focuser to initial position @ " + currentTemp.ToString("0.0") + " C => " + newPosition.ToString("0") + " Steps"; try { if (move > 0) { tsxc.focMoveOut(move); } else { tsxc.focMoveIn(-move); } } catch (Exception ex) { logUpdate += " -- FAILED: " + ex.Message; } } else { logUpdate = "Cannot determine preset position for focuser"; } return(logUpdate); }
/// Windows C# Sample Console Application: Filter /// /// ------------------------------------------------------------------------ /// Vaguely adapted from Filter.vbs (Visual Basic Script) /// Copyright (C) Software Bisque (2009?) /// /// Converted 2017, R.McAlister /// /// ------------------------------------------------------------------------ /// /// This C# console application demonstrates how to connect, change and disconnect a filter. Along the way, most o /// Along the way, most of the basic camera operating methods are also demonstrated. /// public void FilterSample() { ///Global Parameters double dExposure = 10.0; ///seconds int ifilter = 3; ///4nd filter slot, probably clear/lumenscent ///Create camera object and connect ccdsoftCamera tsx_cc = new ccdsoftCamera(); tsx_cc.Connect(); ///Set exposure length tsx_cc.ExposureTime = dExposure; ///Set frame type to Light frame tsx_cc.Frame = ccdsoftImageFrame.cdLight; ///Set filter tsx_cc.FilterIndexZeroBased = ifilter; ///Set preexposure delay tsx_cc.Delay = 5; ///Possible filter change = 5 sec delay ///Set method type to Asynchronous (so we can demo the wait process) tsx_cc.Asynchronous = 0; ///Set for autodark tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; ///Take image tsx_cc.TakeImage(); ///Wait for completion (unnecessary if Asynchronous is set to "False" while (tsx_cc.State == ccdsoftCameraState.cdStateTakePicture) { System.Threading.Thread.Sleep(1000); } ; ///Clean up tsx_cc.Disconnect(); return; }
public Camera(AstroImage asti) { tsxc = new ccdsoftCamera { Autoguider = (int)asti.Camera, BinX = asti.BinX, BinY = asti.BinY, Delay = asti.Delay, Frame = (ccdsoftImageFrame)asti.Frame, ImageReduction = (ccdsoftImageReduction)asti.ImageReduction, Subframe = asti.SubFrame, SubframeBottom = asti.SubframeBottom, SubframeTop = asti.SubframeTop, SubframeRight = asti.SubframeRight, SubframeLeft = asti.SubframeLeft, AutoSaveOn = asti.AutoSave, ExposureTime = asti.Exposure, AutoguiderExposureTime = asti.Exposure }; }
public int ReliableClosedLoopSlew(double RA, double Dec, string name, bool hasDome) { //Tries to perform CLS without running into dome tracking race condition // //First set camera to AutoDark ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.ImageReduction = ccdsoftImageReduction.cdAutoDark; ReliableRADecSlew(RA, Dec, name, hasDome); ClosedLoopSlew tsx_cl = new ClosedLoopSlew(); int clsStatus = 123; //If dome, Turn off tracking if (hasDome) { DomeCouplingOff(); while (clsStatus == 123) { try { clsStatus = tsx_cl.exec(); } catch (Exception ex) { clsStatus = ex.HResult - 1000; }; if (clsStatus == 123) { System.Threading.Thread.Sleep(500); } } DomeCouplingOn(); } else { try { clsStatus = tsx_cl.exec(); } catch (Exception ex) { clsStatus = ex.HResult - 1000; }; } return(clsStatus); }
/// <summary> /// Selects and sets the Reduction Group prior to imaging a light frame /// </summary> /// <param name="filterNumber">Filter to be used</param> /// <param name="exposure">Exposure length of image</param> /// <param name="temperature">Set temperature of camera</param> /// <param name="binning">Set binning level of image</param> /// <returns></returns> public bool SetReductionGroup(int filterNumber, double exposure, int temperature, string binning = "1X1") { { // ccdsoftCamera tsxc = new ccdsoftCamera(); //Translate filterNumber into filterName string filterName = FilterList[filterNumber]; //Build sublist for filterNumber, temperature and binning List <ReductionLibrary> rsubList = LibraryList.Where(x => (x.Filter == filterName) && (x.Temperature == temperature) && (x.Binning == binning)).ToList(); ReductionGroupName = ClosestExposure(rsubList, exposure); if (ReductionGroupName != "") { ReductionGroupName = ReductionGroupName.Remove(0, 6); tsxc.ReductionGroupName = ReductionGroupName; return(true); } else { return(false); } } }
/// Windows C# Sample Console Application: Cam /// /// ------------------------------------------------------------------------ /// Adapted from Cam.vbs (Visual Basic Script) /// Copyright (C) Software Bisque (2013) /// /// Converted 2017, R.McAlister /// /// ------------------------------------------------------------------------ /// /// This C# console application demonstrates the key elements of how to take images using the primary camera. public void CameraSample() { int iCamStatus; ///Create a TSX camera object ccdsoftCamera tsx_cam = new ccdsoftCamera(); ///Connect TSX to the camera try { tsx_cam.Connect(); } catch { MessageBox.Show("Camera Error"); return; }; ///Set the exposure time tsx_cam.ExposureTime = 15.0; ///SEt an exposure delay tsx_cam.Delay = 5.0; ///Set a frame type tsx_cam.Frame = ccdsoftImageFrame.cdLight; ///Set for autodark tsx_cam.ImageReduction = ccdsoftImageReduction.cdAutoDark; ///Set for synchronous imaging (this app will wait until done or error) tsx_cam.Asynchronous = 0; ///Take image iCamStatus = tsx_cam.TakeImage(); if (iCamStatus != 0) { MessageBox.Show("Camera Error: " + iCamStatus.ToString()); } ; ///Disconnect Camera tsx_cam.Disconnect(); }
static double PlateSolve() { //runs an image link on the current location to get PA data //assume camera, mount etc are connected and properly configured. ccdsoftCamera tsxcc = new ccdsoftCamera { Autoguider = 0, Frame = ccdsoftImageFrame.cdLight, ExposureTime = 10, Delay = 0, Asynchronous = 0, AutoSaveOn = 1 }; tsxcc.TakeImage(); ccdsoftImage tsxi = new ccdsoftImage(); ImageLink tsxil = new ImageLink { scale = TSXLink.FOVI.GetFOVScale(), //set Scale pathToFITS = tsxcc.LastImageFileName }; tsxil.execute(); ImageLinkResults tsxir = new ImageLinkResults(); double iPA = tsxir.imagePositionAngle; //Check for image link success, return 0 if not. if (tsxir.succeeded == 1) { return(iPA); } else { return(0); } }
public void AutomatedSearchSample() { /// ******************************************************************************** /// * /// * Below is the flow of program execution /// * See the subroutine TargetLoop to see where the real work is done ///Create Objects sky6RASCOMTele tsx_tele = new sky6RASCOMTele(); ccdsoftCamera tsx_cam = new ccdsoftCamera(); ///Connect Objects try { tsx_tele.Connect(); } catch { MessageBox.Show("Telescope Connect Error"); return;; }; try { tsx_cam.Connect(); } catch { MessageBox.Show("Camera Connection Error"); return;; } ///Run the target loop TargetLoop(); ///Disconnect objects tsx_tele.Disconnect(); tsx_cam.Disconnect(); }
//Autofocus manages the TSX functions to refocus the camera // every change of 1 degree in temperature. //The first fime autofocus is called, the telescope is slewed to // a position with Az = 90, Alt = 80. Then @Focus2 is called with // TSX providing the star to use. the temperature at that time is recorded. //Subsequent calls to autofocus check to see if the current focuser temperature // is more than a degree celsius different from the last @autofocus2 time. // if so, @autofocus2 is called again, although the telescope is not slewed. And so on. /// <summary> /// Checks temp and runs autofocus 2 or 3 if exceeds one degree /// </summary> /// <param name="AtFocus2"></param> /// <returns></returns> public static string Check(bool AtFocus3) { //check to see if current temperature is a degree different from last temperature // If so, then set up and run @focus2 //AtFocus2 chooses to use a 15 degree x 15 degree field of view to choose a focus star // If the current position is close to the meridian then a focus star on the other // side of the meridian can be choosen and the mount will flip trying to get to it // and, if using a dome, the slew does not wait for the dome slit to catch up (CLS flaw) // so not only will an exception be thrown (Dome command in progress Error 125) the first image // will be crap and the focus fail (as of DB 11360). So, this method will point the mount to a // altitude that is no more than 80 degrees at the same azimuth of the current position in order // to avoid a flip and subsequent bullshit happening ccdsoftCamera tsxc = new ccdsoftCamera(); tsxc.Connect(); double currentTemp = tsxc.focTemperature; if (Math.Abs(currentTemp - afLastTemp) > 1) { //Going to have to refocus. ////Move to altitude away from meridian, if need be //sky6RASCOMTele tsxt = new sky6RASCOMTele(); //tsxt.GetAzAlt(); //double tAlt = tsxt.dAlt; //if (tAlt > 80) //{ // double tAz = tsxt.dAz; // tAlt = 80.0; // tsxt.SlewToAzAlt(tAz, tAlt, "AtFocus2ReadyPosition"); //} //reset last temp afLastTemp = currentTemp; int syncSave = tsxc.Asynchronous; tsxc.Asynchronous = 0; if (AtFocus3) { //Set the starchart size to 3 degrees so we minimize the chance of finding a star on // the wrong side of the meridian, if auto-selecting star sky6StarChart tschrt = new sky6StarChart(); tschrt.FieldOfView = 3.0; //run either of the focusing routings try { int focStat = tsxc.AtFocus3(3, true); } catch (Exception e) { tsxc.Asynchronous = syncSave; return("Focus Check: " + e.Message); } } else { try { int focStat = tsxc.AtFocus2(); } catch (Exception e) { tsxc.Asynchronous = syncSave; return("Focus Check: " + e.Message); } //Throw in a 5 sec wait to see if TSX can't set the telescope crosshairs back to original condition System.Threading.Thread.Sleep(5000); } return("Focus Check: Focus successful"); } return("Focus Check: Temperature change less than 1 degree"); }
/// Windows C# Sample Console Application: ImageAnalysis /// /// ------------------------------------------------------------------------ /// /// Author: R.McAlister (2017) /// /// ------------------------------------------------------------------------ /// /// This application demonstrates some of the functionality of the ccdsoftCamera and Image classes /// /// The example takes a 60 second exposure then produces a recommendation window to display computed /// optimal exposure length and duration for a one hour shoot, based on average background noise. /// /// The algorithms are based on work by ... /// John Smith: http://www.hiddenloft.com/notes/SubExposures.pdf /// Charles Anstey: http://www.cloudynights.com/item.php?item_id=1622 /// Steve Cannistra: http://www.starrywonders.com/snr.html /// /// Note: Where the required parameters like "gain" are not supplied through TSX, they are arbitrarily set for /// an SBIG STF8300 /// public void ImageAnalysisSample() { ///Open camera control and connect it to hardware ccdsoftCamera tsx_cc = new ccdsoftCamera(); try { tsx_cc.Connect(); } catch { MessageBox.Show("Camera Connect Error"); }; ///turn on autosave tsx_cc.AutoSaveOn = 1; ///Set for 60 second exposure, light frame with autodark tsx_cc.ExposureTime = 60; tsx_cc.Frame = ccdsoftImageFrame.cdLight; tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; tsx_cc.FilterIndexZeroBased = 3; ///Assumed Lumescent, but change accordingly tsx_cc.Delay = 5; ///Possible filter change = 5 sec delay tsx_cc.Asynchronous = 1; ///Going to do a wait loop tsx_cc.TakeImage(); while (tsx_cc.State == ccdsoftCameraState.cdStateTakePicture) { System.Threading.Thread.Sleep(1000); } ; ///Create image object ccdsoftImage tsx_im = new ccdsoftImage(); int imgerr = 0; ///Open the active image, if any try { imgerr = tsx_im.AttachToActive(); } catch { MessageBox.Show("No Image Available: " + imgerr.ToString()); return; }; const int totalexp = 60; ///Minutes for total exposure sequence double dGain = 0.37; ///electrons per ADU for SBIG STF8000M as spec///d int iPedestal = 0; ///base pedestal double dRnoise = 9.3; ///read out noise in electrons double dNoiseFac = 0.05; ///maximum tolerable contribution of readout noise double dExpFac = 1; ///Exposure reduction factor double dSLambda = 15; ///Faint target ADU minimum double dSNRMax = 0.9; ///fraction of maximum achievable signal to noise ratio (Cannistra) ///Presumably an Image Link has already been performed ///Check on this is TBD int iPX = tsx_im.FITSKeyword("NAXIS1"); int iPY = tsx_im.FITSKeyword("NAXIS2"); int iPXBin = tsx_im.FITSKeyword("XBINNING"); int iPYBin = tsx_im.FITSKeyword("YBINNING"); ///Dim igain as integer = tsx_im.FITSKeyword("EGAIN"); ///TSX doesn///t pick this up, yet double dExpTime = tsx_im.FITSKeyword("EXPTIME"); iPX = iPX - 1; iPY = iPY - 1; double dAvgABU = tsx_im.averagePixelValue(); double dEsky = ((dAvgABU - iPedestal) * dGain) / dExpTime; double dTorn = (System.Math.Pow(dRnoise, 2) / (((System.Math.Pow((1 + dNoiseFac), 2) - 1) * dEsky))); ///Smith algorithm int iExp1 = (int)(dTorn / 2); int iReps1 = (int)((((totalexp * 60) / dTorn) - 1) * 2); ///Anstey algorithm int iExp2 = (int)((dSLambda * System.Math.Sqrt(totalexp * 60)) / (2 * System.Math.Sqrt(dAvgABU / dExpTime))); int iReps2 = (int)((totalexp * 60) / iExp2); ///Cannestr algorithm int iExp3 = (int)((System.Math.Pow(dSNRMax, 2) * System.Math.Pow(dRnoise, 2)) / ((dEsky) * (1 - System.Math.Pow(dSNRMax, 2)))); int iReps3 = (int)((totalexp * 60) / iExp3); ///Display Results MessageBox.Show("Smith Model (at tolerable noise factor = 0.05):" + "\r\n" + " " + iExp1.ToString() + " second exposure with" + "\r\n" + " " + iReps1.ToString() + " repetitions per hour." + "\r\n" + "\r\n" + "Anstey Model (at faint target minimum = 15):" + "\r\n" + " " + iExp2.ToString() + " second exposure with" + "\r\n" + " " + iReps2.ToString() + " repetitions per hour." + "\r\n" + "\r\n" + "Cannestra Model (at SNR = 90% of maximum):" + "\r\n" + " " + iExp3.ToString() + " second exposure with" + "\r\n" + " " + iReps3.ToString() + " repetitions per hour."); return; }
//Find the coordinates of the object galaxyName and perform a slew, then CLS to it. private bool SeekGalaxy() { sky6StarChart tsx_sc = new sky6StarChart(); ClosedLoopSlew tsx_cl = new ClosedLoopSlew(); sky6RASCOMTele tsx_mt = new sky6RASCOMTele(); sky6Raven tsx_rv = new sky6Raven(); sky6ObjectInformation tsx_obj = new sky6ObjectInformation(); //Clear any camera set up stuff that might be hanging around // and there has been some on occasion //Removed subframe on request for cameras with long download times ccdsoftCamera tsx_cc = new ccdsoftCamera() { //Subframe = 0, Delay = 0 }; LogEntry("Finding coordinates for " + freshImageName); tsx_sc.Find(freshImageName); // Perform slew to new location before starting CLS -- TSX does not wait for dome rotation. tsx_obj.Property(Sk6ObjectInformationProperty.sk6ObjInfoProp_RA_2000); double tRA = tsx_obj.ObjInfoPropOut; tsx_obj.Property(Sk6ObjectInformationProperty.sk6ObjInfoProp_DEC_2000); double tDec = tsx_obj.ObjInfoPropOut;; //Make sure that the mount commands are synchronous tsx_mt.Asynchronous = 0; //LogEntry("Initial slew to target"); ////Slew the mount and dome should follow before completion... // try { tsx_mt.SlewToRaDec(tRA, tDec, freshImageName); } //catch (Exception ex) { LogEntry("Slew error: " + ex.Message); } //Test to see if a dome tracking operation is underway. // If so, doing a IsGotoComplete will throw an Error 212. // Ignore it a wait a few seconds for stuff to clear //If using dome, toggle dome coupling: this appears to clear most Error 123 problems Configuration ss_cfg = new Configuration(); bool hasDome = Convert.ToBoolean(ss_cfg.UsesDome); if (hasDome) { sky6Dome tsx_dm = new sky6Dome(); tsx_dm.IsCoupled = 0; System.Threading.Thread.Sleep(1000); tsx_dm.IsCoupled = 1; } //Wait for any Error 123//s to clear LogEntry("Precision slew (CLS) to target"); //Now try the CLS, but if an Error 123 is thrown, keep trying // every five seconds until the dome slew catches up. //int clsStatus = 123; //while (clsStatus == 123) //{ // try { clsStatus = tsx_cl.exec(); } // catch (Exception ex) // { // clsStatus = ex.HResult - 1000; // LogEntry("CLS Error: " + ex.Message); // }; //} DeviceControl dctl = new DeviceControl(); int clsStatus = dctl.ReliableClosedLoopSlew(tRA, tDec, freshImageName, hasDome); LogEntry("Precision Slew Complete: "); if (clsStatus == 0) { LogEntry(" CLS successful"); return(true); } else { LogEntry(" CLS unsucessful: Error: " + clsStatus.ToString()); return(false); } }
/// Windows C# Sample Console Application: AutoGuide /// /// ------------------------------------------------------------------------ /// /// Author: R.McAlister (2017) /// /// ------------------------------------------------------------------------ /// /// This application performs the following steps: /// Finds a target, M39 in this case /// Turns off Autoguiding (if on) /// Performs a Closed Loop Slew to the target /// Takes an image with the Autoguide camera /// Turns on Autoguiding /// /// public void AutoGuideSample() { ///Set connection to star chart and perform a find on M39 -- this will set the target for a CLS sky6StarChart tsx_sc = new sky6StarChart(); tsx_sc.Find("M39"); ///Create connection to autoguide camera and connect ccdsoftCamera tsx_ag = new ccdsoftCamera(); ///Attach this object to the guider camera tsx_ag.Autoguider = 1; ///Find out with the guide camera is up to. Abort if autoguiding or calibrating if (tsx_ag.Connect() == 0) { if ((tsx_ag.State == ccdsoftCameraState.cdStateAutoGuide) | (tsx_ag.State == ccdsoftCameraState.cdStateCalibrate)) { tsx_ag.Abort(); } ; } ; ///Create closed loop slew object ClosedLoopSlew tsx_cls = new ClosedLoopSlew(); ///Set the exposure, filter to luminance and reduction, set the camera delay to 0 -- backlash /// should be picked up in the mount driver ccdsoftCamera tsx_cc = new ccdsoftCamera(); tsx_cc.ImageReduction = ccdsoftImageReduction.cdAutoDark; tsx_cc.FilterIndexZeroBased = 3; ///Luminance tsx_cc.ExposureTime = 10; tsx_cc.Delay = 0; ///run CLS synchronously ///tsx_cls.Asynchronous = False ///-- this setting doesn///t appear to work (member not found) as of DB8458 ///Execute try { int clsstat = tsx_cls.exec(); } catch { ///Just close up: TSX will spawn error window MessageBox.Show("Closed Loop Slew error"); return; ///Let it go for demo purposes }; ///Connect AutoGuide camera in case it isn///t try { tsx_ag.Connect(); } catch { MessageBox.Show("Guide camera connect error"); return; }; ///Take an image to use for Autoguiding, run the function synchronously tsx_ag.ExposureTime = 2; tsx_ag.Asynchronous = 0; tsx_ag.Subframe = 0; var tstat = tsx_ag.TakeImage(); ///Just assume it works ///Turn asynchronous back on to get out of this tsx_ag.Asynchronous = 1; ///Fire off Autoguiding tsx_ag.Autoguide(); return; }
public static string LookUpFilterName(int filterIndex) { ccdsoftCamera tsxc = new ccdsoftCamera(); return(tsxc.szFilterName(filterIndex)); }
public static bool CLSToTarget(string tgtName, SpeedVector sv, bool IsPrecision = false) { //first, couple dome to telescope, if there is one sky6Dome tsxd = new sky6Dome(); try { tsxd.Connect(); tsxd.IsCoupled = 1; } catch (Exception ex) { //do nothing } int clsStatus = 123; sky6RASCOMTele tsxmt = new sky6RASCOMTele(); ClosedLoopSlew tsx_cl = new ClosedLoopSlew(); sky6StarChart tsxsc = new sky6StarChart(); sky6Utils tsxu = new sky6Utils(); //Check to see if target is above horizon double tgtRAH = Transform.DegreesToHours(sv.RA_Degrees); double tgtDecD = sv.Dec_Degrees; tsxu.ConvertRADecToAzAlt(tgtRAH, tgtDecD); double tgtAzmD = tsxu.dOut0; double tgtAltD = tsxu.dOut1; if (tgtAltD <= 0) { MessageBox.Show("Slew failure: Target is below the horizon"); return(false); } //Clear any image reduction, otherwise full reduction might cause a problem ccdsoftCamera tsxcam = new ccdsoftCamera() { ImageReduction = ccdsoftImageReduction.cdNone, Asynchronous = 1 //make sure nothing else happens while setting this up }; //Abort any ongoing imaging tsxcam.Abort(); bool returnStatus = true; // diagnostic string strRA = Utils.HourString(tgtRAH, false); string strDec = Utils.DegreeString(tgtDecD, false); // tsxsc.Find(tgtRAH.ToString() + ", " + tgtDecD.ToString()); tsxmt.Connect(); tsxu.Precess2000ToNow(tgtRAH, tgtDecD); double jnRAH = tsxu.dOut0; double jnDecD = tsxu.dOut1; //tsxmt.Asynchronous = 0; try { tsxmt.SlewToRaDec(jnRAH, jnDecD, tgtName); } catch (Exception ex) { MessageBox.Show("Slew Failure: " + ex.Message); returnStatus = false; } if (IsPrecision && returnStatus) { //*** precision slew try { clsStatus = tsx_cl.exec(); } catch (Exception ex) { returnStatus = false; } } try { tsxsc.Find(tgtName); } catch (Exception ex) { returnStatus = true; } return(returnStatus); }
/// Windows C# Sample Console Application: ListSearch /// /// ------------------------------------------------------------------------ /// Vaguely adapted from ErrorHandling.vbs (Visual Basic Script) /// Copyright (C) Software Bisque (2013) /// /// Converted 2015, R.McAlister /// /// ------------------------------------------------------------------------ /// /// This C# console application demonstrates how to run the telescope through a list of targets as defined /// by a list of names. /// /// Note: The gist of the orginal VBS script was entitled "ErrorHandling.vbs". However, that /// script, however labeled, performed the functions as adapted to VB herein. /// public void ListSearchSample() { ///Set the exposure time for the image double dExposure = 1.0; ///Target List string[] targetlist = new string[] { "NGC1348", "NGC1491", "NGC1708", "NGC179", "NGC1798", "NGC2165", "NGC2334", "NGC2436", "NGC2519", "NGC2605", "NGC2689", "NGC2666", "NGC4381", "NGC5785", "NGC5804", "NGC6895", "NGC6991", "NGC7011", "NGC7058", "M39", "NGC7071", "NGC7150", "NGC7295", "NGC7394", "NGC7686", "NGC7801" }; ///Create objects sky6StarChart objChrt = new sky6StarChart(); sky6RASCOMTele objTele = new sky6RASCOMTele(); ccdsoftCamera objCam = new ccdsoftCamera(); sky6Utils objUtil = new sky6Utils(); sky6ObjectInformation objInfo = new sky6ObjectInformation(); ///Connect Objects objTele.Connect(); objCam.Connect(); ///Run loop over array of target names double dAlt; double dAz; bool iError; foreach (string target in targetlist) { objChrt.Find(target); objInfo.Property(Sk6ObjectInformationProperty.sk6ObjInfoProp_ALT); dAlt = objInfo.ObjInfoPropOut; objInfo.Property(Sk6ObjectInformationProperty.sk6ObjInfoProp_AZM); dAz = objInfo.ObjInfoPropOut; try { objTele.SlewToAzAlt(dAz, dAlt, target); } catch { MessageBox.Show("An error has occurred running slew"); return; }; ///Set exposure time and try for image, exit if error objCam.ExposureTime = dExposure; try { objCam.TakeImage(); } catch { MessageBox.Show("An error has occurred running image"); }; } ///Disconnect telescope and camera objTele.Disconnect(); objCam.Disconnect(); return; }