private void LocateTwoStarsWithStarRecognition(List <PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels) { TrackedObject trackedObject1 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]); TrackedObject trackedObject2 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]); LocateTwoStarsWithStarRecognition(stars, astroImage, pixels, trackedObject1, trackedObject2); }
/// <summary> /// Zdarzenie wywoływane gdy obiekt wedźie w pole wykrywania /// </summary> /// <param name="collision"></param> public void OnTriggerEnter2D(Collider2D collision) { if (Filter(collision.gameObject) && !TrackedObjects.Exists(obj => obj == collision.gameObject)) { TrackedObjects.Add(collision.gameObject); } }
private void LocateStarsWithStarRecognition(IAstroImage astroImage) { EnsureComputedRefinedData(); if (m_MinLocateDistance > 8) { if (!LightCurveReductionContext.Instance.WindOrShaking) { //TODO: If the wind flag is not set, then use a 3 frame binned integration to locate the stars on } uint[,] pixels = astroImage.GetPixelsCopy(); List <PotentialStarStruct> peakPixels = new List <PotentialStarStruct>(); AutoDiscoveredStars.Clear(); AutoDiscoveredStars = StarFinder.GetStarsInArea( ref pixels, astroImage.BitPix, astroImage.MaxSignalValue, TangraConfig.PreProcessingFilter.NoFilter, peakPixels, null, (uint)Math.Round(TangraConfig.Settings.Special.LostTrackingMinSignalCoeff * m_MinLocateSignal), TangraConfig.Settings.Special.LostTrackingMinDistance, false, LightCurveReductionContext.Instance.OSDFrame, ReducePeakPixels); Stopwatch sw = new Stopwatch(); sw.Start(); if (m_LocateObjects.Count == 1 && AutoDiscoveredStars.Count == 1) { LocateSingleStarsWithStarRecognition(AutoDiscoveredStars, astroImage); } else if ( m_LocateObjects.Count == 2 && peakPixels.Count > 1) { LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels); } else if ( m_LocateObjects.Count > 2 && peakPixels.Count > 1) { List <TrackedObject> goodTrackedObjects = TrackedObjects.Cast <TrackedObject>().ToList().FindAll(t => t.LastKnownGoodPosition != null); if (goodTrackedObjects.Count < 2) { // We don't have at least one good pair. Fail. } else if (goodTrackedObjects.Count >= 2) { goodTrackedObjects.Sort((a, b) => Math.Min(b.LastKnownGoodPosition.XDouble, b.LastKnownGoodPosition.YDouble).CompareTo( Math.Min(a.LastKnownGoodPosition.XDouble, a.LastKnownGoodPosition.YDouble))); Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: Using objects {0} and {1}", goodTrackedObjects[0].TargetNo, goodTrackedObjects[1].TargetNo)); // There is only 1 good pair so fallback to using 2 star recognition LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels, goodTrackedObjects[0], goodTrackedObjects[1]); } } sw.Stop(); Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00"))); } }
private void EnsureComputedRefinedData() { if (!float.IsNaN(m_MinLocateSignal)) { m_LocateObjects.Clear(); for (int i = 0; i < TrackedObjects.Count; i++) { if ( (!(TrackedObjects[i] as TrackedObject).IsOccultedStar || !LightCurveReductionContext.Instance.FullDisappearance) && !TrackedObjects[i].IsOffScreen && !float.IsNaN((TrackedObjects[i] as TrackedObject).LastFrameX) ) { // Don't include targets offscreen, or targets that were not found during the last tracking (could have been off screen) m_LocateObjects.Add((TrackedObjects[i] as TrackedObject).TargetNo); } } return; } m_MinLocateSignal = TrackedObjects.Cast <TrackedObject>().Min(o => o.RefinedOrLastSignalLevel == 0 ? 255f : o.RefinedOrLastSignalLevel); // Locate all peak pixels with signal higher than (minSignal + medianNoise) / 2 m_MinLocateSignal = (m_MedianValue + m_MinLocateSignal) / 2f; double minDistance = double.MaxValue; for (int i = 0; i < TrackedObjects.Count; i++) { if ((!(TrackedObjects[i] as TrackedObject).IsOccultedStar && !TrackedObjects[i].IsOffScreen) || !LightCurveReductionContext.Instance.FullDisappearance) { m_LocateObjects.Add((TrackedObjects[i] as TrackedObject).TargetNo); } for (int j = 0; j < TrackedObjects.Count; j++) { if (i == j) { continue; } double dist = ImagePixel.ComputeDistance( TrackedObjects[i].OriginalObject.ApertureStartingX, TrackedObjects[j].OriginalObject.ApertureStartingX, TrackedObjects[i].OriginalObject.ApertureStartingY, TrackedObjects[j].OriginalObject.ApertureStartingY); if (minDistance > dist) { minDistance = dist; } } } m_MinLocateDistance = minDistance / 2.0; }
public StarFieldTracker(List <TrackedObjectConfig> measuringStars) { int i = -1; foreach (var originalObject in measuringStars) { i++; TrackedObject trackedObject = new TrackedObject((byte)i, originalObject); TrackedObjects.Add(trackedObject); TrackedObjectsByTargetId.Add(trackedObject.TargetNo, trackedObject); } }
private void LocateSingleStarsWithStarRecognition(List <PSFFit> stars, IAstroImage astroImage) { TrackedObject trackedObject = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]); trackedObject.ThisFrameX = (float)stars[0].XCenter; trackedObject.ThisFrameY = (float)stars[0].YCenter; trackedObject.PSFFit = stars[0]; trackedObject.ThisFrameCertainty = (float)stars[0].Certainty; trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition); AutoDiscoveredStars.Clear(); if (TrackedObjects.Count > 1 && LocateFirstObjects.Contains(trackedObject)) { // If guiding star then run the locate second objects again ReLocateNonGuidingObjects(astroImage); } }
private void ReducePeakPixels2Targets(List <PotentialStarStruct> potentialStars) { const double TOLERANCE = 9; List <int> possibleStarIndexes = new List <int>(); TrackedObject trackedObject1 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]) as TrackedObject; TrackedObject trackedObject2 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]) as TrackedObject; if (trackedObject1.TargetNo != trackedObject2.TargetNo && trackedObject1.LastKnownGoodPosition != null && trackedObject2.LastKnownGoodPosition != null) { double deltaX = Math.Abs(trackedObject1.LastKnownGoodPosition.X - trackedObject2.LastKnownGoodPosition.X); double deltaY = Math.Abs(trackedObject1.LastKnownGoodPosition.Y - trackedObject2.LastKnownGoodPosition.Y); for (int i = 0; i < potentialStars.Count; i++) { for (int j = i + 1; j < potentialStars.Count; j++) { PotentialStarStruct px1 = potentialStars[i]; PotentialStarStruct px2 = potentialStars[j]; double distX = Math.Abs(px1.X - px2.X); double distY = Math.Abs(px1.Y - px2.Y); if (Math.Abs(distX - deltaX) < TOLERANCE && Math.Abs(distY - deltaY) < TOLERANCE) { possibleStarIndexes.Add(i); possibleStarIndexes.Add(j); } } } } for (int i = potentialStars.Count - 1; i >= 0; i--) { if (possibleStarIndexes.IndexOf(i) == -1) { potentialStars.RemoveAt(i); } } }
/// <summary> /// Function to create an 2D specific effect object. /// </summary> /// <typeparam name="T">Type of effect to create.</typeparam> /// <param name="name">Name of the effect.</param> /// <param name="parameters">Parameters used to initialize the effect.</param> /// <returns>The new effect object.</returns> /// <remarks>Effects are used to simplify rendering with multiple passes when using a shader.</remarks> /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="name"/> parameter is NULL (Nothing in VB.Net).</exception> /// <exception cref="System.ArgumentException">Thrown when the name parameter is an empty string.</exception> public T Create2DEffect <T>(string name, params GorgonEffectParameter[] parameters) where T : Gorgon2DEffect { var effectParameters = new GorgonEffectParameter[parameters == null ? 1 : parameters.Length + 1]; effectParameters[0] = new GorgonEffectParameter("Gorgon2D", this); if (parameters == null) { return(Graphics.ImmediateContext.Shaders.CreateEffect <T>(name, effectParameters)); } for (int i = 0; i < parameters.Length; i++) { effectParameters[i + 1] = parameters[i]; } var result = Graphics.ImmediateContext.Shaders.CreateEffect <T>(name, effectParameters); TrackedObjects.Add(result); return(result); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> private void Dispose(bool disposing) { if (_disposed) { return; } if (disposing) { // Dump any pending rendering. _cache.Reset(); if (_initialState != null) { _initialState.Restore(true); _initialState = null; } TrackedObjects.ReleaseAll(); if (Effects != null) { Effects.FreeEffects(); Effects = null; } if (_currentTarget.SwapChain != null) { _currentTarget.SwapChain.AfterSwapChainResized -= target_Resized; } if (DefaultLayout != null) { DefaultLayout.Dispose(); } if (VertexShader != null) { VertexShader.CleanUp(); } if (PixelShader != null) { PixelShader.CleanUp(); } VertexShader = null; PixelShader = null; DefaultVertexBufferBinding.VertexBuffer.Dispose(); if (DefaultIndexBuffer != null) { DefaultIndexBuffer.Dispose(); } if ((_systemCreatedTarget) && (_defaultTarget.Target != null)) { _defaultTarget.Target.Resource.Dispose(); _defaultTarget = default(Gorgon2DTarget); } Graphics.RemoveTrackedObject(this); } _disposed = true; }
public MainViewModel(IMainModel model, ICttObjectTrackingService cttObjectTrackingService, INavigationService navigationService, ISystemTrayService systemTrayService, IMessageBoxService messageBoxService, IClipboardService clipboardService, IEmailComposeService emailComposeService, ISmsComposeService smsComposeService) { _model = model; _cttObjectTrackingService = cttObjectTrackingService; _navigationService = navigationService; _systemTrayService = systemTrayService; _messageBoxService = messageBoxService; _clipboardService = clipboardService; _emailComposeService = emailComposeService; _smsComposeService = smsComposeService; TrackedObjects = _model.TrackedObjects .Select(x => new ObjectDetailsViewModel(x)) .ToObservableCollection(); ShowObjectDetailsCommand = new RelayCommand <ObjectDetailsViewModel>(item => { var objectId = item.Model.ObjectId; _navigationService.NavigateTo(new Uri("/View/ObjectDetailsPage.xaml?" + objectId, UriKind.Relative)); }); NewObjectCommand = new RelayCommand(() => { _navigationService.NavigateTo(new Uri("/View/NewObjectPage.xaml", UriKind.Relative)); }, () => !IsBusy); EnableSelectionCommand = new RelayCommand(() => { IsSelectionEnabled = true; }, () => !IsTrackedObjectsEmpty && !IsBusy); RefreshCommand = new RelayCommand(() => { var enumerator = TrackedObjects.GetEnumerator(); RefreshNext(enumerator); }, () => !IsTrackedObjectsEmpty && !IsBusy); DeleteObjectsCommand = new RelayCommand <IList>(items => { if (items == null || items.Count == 0) { return; } _messageBoxService.Show("Está prestes a apagar os objectos seleccionados", "Tem a certeza?", new string[] { "eliminar", "cancelar" }, button => { if (button != 0) { return; } var itemsToRemove = items .Cast <ObjectDetailsViewModel>() .ToArray(); foreach (var item in itemsToRemove) { _model.TrackedObjects.Remove(item.Model); TrackedObjects.Remove(item); } IsTrackedObjectsEmpty = (TrackedObjects.Count == 0); _model.Save(); }); }, items => !IsBusy); ShowAboutCommand = new RelayCommand(() => { _navigationService.NavigateTo(new Uri("/View/AboutPage.xaml", UriKind.Relative)); }); BackKeyPressCommand = new RelayCommand <CancelEventArgs>(e => { if (IsSelectionEnabled) { IsSelectionEnabled = false; e.Cancel = true; } }); CopyCodeCommand = new RelayCommand <ObjectDetailsViewModel>(item => { _clipboardService.SetText(item.Model.ObjectId); }); MailCodeCommand = new RelayCommand <ObjectDetailsViewModel>(item => { _emailComposeService.Show("CTT Objectos", string.Format("\nO seu código de tracking: {0}\n\nPode consultar o estado entrando em http://www.ctt.pt e utilizando a opção \"Pesquisa de Objectos\".\n\nEnviado por CTT Objectos (http://bit.ly/cttobjectos)", item.Model.ObjectId)); }); TextCodeCommand = new RelayCommand <ObjectDetailsViewModel>(item => { _smsComposeService.Show(string.Empty, item.Model.ObjectId); }); MessengerInstance.Register <AddObjectMessage>(this, message => { var objectViewModel = TrackedObjects.FirstOrDefault(x => x.Model.ObjectId == message.Model.ObjectId); if (objectViewModel == null) { var objectModel = new ObjectModel(message.Description, message.ETag, message.Model); _model.TrackedObjects.Add(objectModel); TrackedObjects.Add(new ObjectDetailsViewModel(objectModel)); IsTrackedObjectsEmpty = false; } else { objectViewModel.Model.Description = message.Description; objectViewModel.Model.State = message.Model; } _model.Save(); }); IsTrackedObjectsEmpty = (TrackedObjects.Count == 0); }
/// <summary> /// Przestaje śledzić obiekt kótry wyszedł poza pole wykrywania /// </summary> /// <param name="collision"></param> public void OnTriggerExit2D(Collider2D collision) { TrackedObjects.Remove(collision.gameObject); }
public override void NextFrame(int frameNo, IAstroImage astroImage) { base.NextFrame(frameNo, astroImage); #region run the full star recognition recovery if enabled if (TangraConfig.Settings.Tracking.RecoverFromLostTracking && m_RefiningFramesLeft <= 0) { bool notAllStarsLocated = TrackedObjects.Exists(o => !o.IsLocated); bool notAllLocateFirstStarsLocated = LocateFirstObjects.Exists(o => !o.IsLocated); if (notAllLocateFirstStarsLocated && LocateFirstObjects.Count > 1) { LocateStarsWithStarRecognition(astroImage); } // TODO: Use the notAllStarsLocated to troubleshoot the pattern recognition alignment } #endregion bool allGuidingStarsLocated = true; foreach (TrackedObject trackedObject in LocateFirstObjects) { if (!trackedObject.IsLocated && !trackedObject.IsOffScreen) { allGuidingStarsLocated = false; } } if (m_RefiningFramesLeft > 0) { if (allGuidingStarsLocated) { m_RefiningFramesLeft--; } } else { m_IsTrackedSuccessfully = LocateFirstObjects.Count > 0 ? allGuidingStarsLocated : OccultedStar.IsLocated; } if (!m_Refining && (LocateFirstObjects.Count > 0 && allGuidingStarsLocated) && (LightCurveReductionContext.Instance.FieldRotation || LightCurveReductionContext.Instance.LightCurveReductionType == LightCurveReductionType.MutualEvent)) { for (int i = 0; i < TrackedObjects.Count; i++) { TrackedObject obj1 = TrackedObjects[i] as TrackedObject; for (int j = 0; j < TrackedObjects.Count; j++) { if (i == j) { continue; } TrackedObject obj2 = TrackedObjects[j] as TrackedObject; long pairId = (((long)obj1.TargetNo) << 32) + (long)obj2.TargetNo; double oldDistance = m_RefinedDistances[pairId]; double newDistance = ImagePixel.ComputeDistance( obj1.Center.XDouble, obj2.Center.XDouble, obj1.Center.YDouble, obj2.Center.YDouble); m_RefinedDistances[pairId] = (oldDistance + newDistance) / 2.0; LocationVector vector = obj1.OtherGuidingStarsLocationVectors[obj2.TargetNo]; vector.DeltaXToAdd = (vector.DeltaXToAdd + obj2.Center.XDouble - obj1.Center.XDouble) / 2; vector.DeltaYToAdd = (vector.DeltaYToAdd + obj2.Center.YDouble - obj1.Center.YDouble) / 2; } } } if (!m_IsTrackedSuccessfully) { // If the tracking has failed, then some objects may be offscreen and have NaN position // So inherit the IsOffScreen flag from the previous position foreach (TrackedObject obj in TrackedObjects) { if (m_IsOffScreenPrev[obj.TargetNo] && double.IsNaN(obj.Center.XDouble)) { obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen); } } } else { foreach (TrackedObject obj in TrackedObjects) { m_IsOffScreenPrev[obj.TargetNo] = obj.IsOffScreen; } } }