public async Task <PlateSolveResult> Center(CaptureSequence seq, CenterSolveParameter parameter, IProgress <PlateSolveProgress> solveProgress, IProgress <ApplicationStatus> progress, CancellationToken ct) { if (parameter?.Coordinates == null) { throw new ArgumentException(nameof(CenterSolveParameter.Coordinates)); } if (parameter?.Threshold <= 0) { throw new ArgumentException(nameof(CenterSolveParameter.Threshold)); } var centered = false; PlateSolveResult result; Separation offset = new Separation(); do { result = await CaptureSolver.Solve(seq, parameter, solveProgress, progress, ct); if (result.Success == false) { //Solving failed. Give up. break; } var position = (telescopeMediator.GetCurrentPosition() - offset).Transform(result.Coordinates.Epoch); result.Separation = result.DetermineSeparation(position); Logger.Debug($"Centering Solver - Scope Position: {position}; Centering Coordinates: {parameter.Coordinates}; Solve Result: {result.Coordinates}; Separation {result.Separation}"); solveProgress?.Report(new PlateSolveProgress() { PlateSolveResult = result }); if (Math.Abs(result.Separation.Distance.ArcMinutes) > parameter.Threshold) { progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceSyncing"] }); if (parameter.NoSync || !await telescopeMediator.Sync(result.Coordinates)) { offset = result.DetermineSeparation(position + offset); Logger.Debug($"Sync failed - calculating offset instead to compensate. Original: {position.Transform(result.Coordinates.Epoch)}; Solved: {result.Coordinates}; Offset: {offset}"); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveSyncViaTargetOffset"] }); } else { var positionAfterSync = telescopeMediator.GetCurrentPosition().Transform(result.Coordinates.Epoch); if (Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.RADegrees - result.Coordinates.RADegrees)) > 1 || Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.Dec - result.Coordinates.Dec)) > 1) { offset = result.DetermineSeparation(positionAfterSync); Logger.Debug($"Sync failed silently - calculating offset instead to compensate. Original: {positionAfterSync}; Solved: {result.Coordinates}; Offset: {offset}"); } else { // Sync worked - reset offset Logger.Debug("Synced sucessfully"); offset = new Separation(); } } Logger.Trace($"Slewing to target after sync. Target coordinates RA: {parameter.Coordinates.RAString} Dec: {parameter.Coordinates.DecString} Epoch: {parameter.Coordinates.Epoch}"); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceReslew"] }); await telescopeMediator.SlewToCoordinatesAsync(parameter.Coordinates + offset); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceRepeating"] }); } else { centered = true; } } while (!centered); return(result); }
private async Task <bool> CaptureSolveSyncAndReslew(IProgress <ApplicationStatus> progress) { _solveCancelToken?.Dispose(); _solveCancelToken = new CancellationTokenSource(); try { if ((this.Sync || this.SlewToTarget) && !telescopeInfo.Connected) { throw new Exception(Locale.Loc.Instance["LblTelescopeNotConnected"]); } var seq = new CaptureSequence(SnapExposureDuration, CaptureSequence.ImageTypes.SNAPSHOT, SnapFilter, SnapBin, 1); seq.Gain = SnapGain; var plateSolver = PlateSolverFactory.GetPlateSolver(profileService.ActiveProfile.PlateSolveSettings); var blindSolver = PlateSolverFactory.GetBlindSolver(profileService.ActiveProfile.PlateSolveSettings); var solveProgress = new Progress <PlateSolveProgress>(x => { if (x.PlateSolveResult != null) { PlateSolveResult = x.PlateSolveResult; } }); if (this.SlewToTarget) { var solver = new CenteringSolver(plateSolver, blindSolver, imagingMediator, telescopeMediator); var parameter = new CenterSolveParameter() { Attempts = 1, Binning = SnapBin?.X ?? CameraInfo.BinX, Coordinates = telescopeMediator.GetCurrentPosition(), DownSampleFactor = profileService.ActiveProfile.PlateSolveSettings.DownSampleFactor, FocalLength = profileService.ActiveProfile.TelescopeSettings.FocalLength, MaxObjects = profileService.ActiveProfile.PlateSolveSettings.MaxObjects, PixelSize = profileService.ActiveProfile.CameraSettings.PixelSize, ReattemptDelay = TimeSpan.FromMinutes(profileService.ActiveProfile.PlateSolveSettings.ReattemptDelay), Regions = profileService.ActiveProfile.PlateSolveSettings.Regions, SearchRadius = profileService.ActiveProfile.PlateSolveSettings.SearchRadius, Threshold = RepeatThreshold, NoSync = profileService.ActiveProfile.TelescopeSettings.NoSync }; _ = await solver.Center(seq, parameter, solveProgress, progress, _solveCancelToken.Token); } else { var solver = new CaptureSolver(plateSolver, blindSolver, imagingMediator); var parameter = new CaptureSolverParameter() { Attempts = 1, Binning = SnapBin?.X ?? CameraInfo.BinX, DownSampleFactor = profileService.ActiveProfile.PlateSolveSettings.DownSampleFactor, FocalLength = profileService.ActiveProfile.TelescopeSettings.FocalLength, MaxObjects = profileService.ActiveProfile.PlateSolveSettings.MaxObjects, PixelSize = profileService.ActiveProfile.CameraSettings.PixelSize, ReattemptDelay = TimeSpan.FromMinutes(profileService.ActiveProfile.PlateSolveSettings.ReattemptDelay), Regions = profileService.ActiveProfile.PlateSolveSettings.Regions, SearchRadius = profileService.ActiveProfile.PlateSolveSettings.SearchRadius, Coordinates = telescopeMediator.GetCurrentPosition() }; var result = await solver.Solve(seq, parameter, solveProgress, progress, _solveCancelToken.Token); if (telescopeInfo.Connected) { var position = parameter.Coordinates.Transform(result.Coordinates.Epoch); result.Separation = result.DetermineSeparation(position); } if (!profileService.ActiveProfile.TelescopeSettings.NoSync && Sync) { await telescopeMediator.Sync(result.Coordinates); } } } catch (OperationCanceledException) { } catch (Exception ex) { Logger.Error(ex); Notification.ShowError(ex.Message); } return(true); }