/// <summary> /// Creates a new instance of our transmitting phone /// with default configuration and graphics. /// </summary> /// <returns>A new SimpleDigitalTransmitter.</returns> private SimpleDigitalTransmitter CreateTransmittingPhone() { var earth = CentralBodiesFacet.GetFromContext().Earth; // Create a new SimpleDigitalTransmitter and assign its basic properties. // Even though we are using a static location for our transmitter, // it can easily be changed to a moving one by simply modifying the // LocationPoint to something else, for example a route generated // with the Route Design Library. double longitude = Trig.DegreesToRadians(39.6333); double latitude = Trig.DegreesToRadians(11.1333); var phone = new SimpleDigitalTransmitter { Name = "Dessie, Ethiopia", LocationPoint = new PointCartographic(earth, new Cartographic(longitude, latitude, 0.0)), CarrierFrequency = m_intendedSignal.TargetFrequency, EffectiveIsotropicRadiatedPower = CommunicationAnalysis.FromDecibels(m_transmitPowerTrackBar.Value), DataRate = 50000.0 }; //Add a default marker phone.Extensions.Add(new MarkerGraphicsExtension(new MarkerGraphics { Texture = new ConstantGraphicsParameter <Texture2D>(m_phoneTexture) })); //Add a label based on the name and show just below the marker. var textGraphics = new TextGraphics { Color = new ConstantGraphicsParameter <Color>(Color.Yellow), Font = new ConstantGraphicsParameter <Font>(m_labelFont), Outline = new ConstantGraphicsParameter <bool>(true), OutlineColor = new ConstantGraphicsParameter <Color>(Color.Black), Text = new ConstantGraphicsParameter <string>(phone.Name), Origin = new ConstantGraphicsParameter <Origin>(Origin.TopCenter), PixelOffset = new ConstantGraphicsParameter <PointF>(new PointF(0, -m_phoneTexture.Template.Height / 2)), DisplayParameters = { MaximumDistance = new ConstantGraphicsParameter <double>(75000000.0) } }; if (TextureFilter2D.Supported(TextureWrap.ClampToEdge)) { textGraphics.TextureFilter = new ConstantGraphicsParameter <TextureFilter2D>(TextureFilter2D.NearestClampToEdge); } phone.Extensions.Add(new TextGraphicsExtension(textGraphics)); return(phone); }
/// <summary> /// Creates a new instance of our receiving phone /// with default configuration and graphics. /// </summary> /// <returns>A new SimpleReceiver.</returns> private SimpleReceiver CreateReceivingPhone() { var earth = CentralBodiesFacet.GetFromContext().Earth; // Create a receiving phone with a gain of 100 and a noisefactor of 2 - adding 290 Kelvin worth of noise to the call. // Even though we are using a static location for our receiver, // it can easily be changed to a moving one by simply modifying the // LocationPoint to something else, for example a route generated // with the Route Design Library. double longitude = Trig.DegreesToRadians(77.5833); double latitude = Trig.DegreesToRadians(12.9833); var phone = new SimpleReceiver { Name = "Bangalore, India", LocationPoint = new PointCartographic(earth, new Cartographic(longitude, latitude, 0)), Gain = 100.0, NoiseFactor = 2.0, TargetFrequency = m_intendedSignal.TargetFrequency }; //Add a default marker phone.Extensions.Add(new MarkerGraphicsExtension(new MarkerGraphics { Texture = new ConstantGraphicsParameter <Texture2D>(m_phoneTexture) })); //Add a label based on the name and show just below the marker. var textGraphics = new TextGraphics { Color = new ConstantGraphicsParameter <Color>(Color.Yellow), Font = new ConstantGraphicsParameter <Font>(m_labelFont), Outline = new ConstantGraphicsParameter <bool>(true), OutlineColor = new ConstantGraphicsParameter <Color>(Color.Black), Text = new ConstantGraphicsParameter <string>(phone.Name), Origin = new ConstantGraphicsParameter <Origin>(Origin.TopCenter), PixelOffset = new ConstantGraphicsParameter <PointF>(new PointF(0, -m_phoneTexture.Template.Height / 2)), DisplayParameters = { MaximumDistance = new ConstantGraphicsParameter <double>(75000000.0) } }; if (TextureFilter2D.Supported(TextureWrap.ClampToEdge)) { textGraphics.TextureFilter = new ConstantGraphicsParameter <TextureFilter2D>(TextureFilter2D.NearestClampToEdge); } phone.Extensions.Add(new TextGraphicsExtension(textGraphics)); return(phone); }
static void Main(string[] args) { // 球坐标转为笛卡尔坐标 var spherical0 = new Spherical(Math.PI / 4, Math.PI / 8, 100.0); var cartesian0 = new Cartesian(spherical0); Console.WriteLine("球坐标:{0};笛卡尔坐标:{1}", spherical0, cartesian0); // 笛卡尔坐标归一化 UnitCartesian unitCartesian1 = cartesian0.Normalize(); Console.WriteLine("单位矢量笛卡尔坐标:{0}", unitCartesian1); // 地图坐标转为笛卡尔坐标 var cartographic2 = new Cartographic(Trig.DegreesToRadians(120), Trig.DegreesToRadians(30), 100); EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; Cartesian cartesian2 = earth.Shape.CartographicToCartesian(cartographic2); Console.WriteLine("地图坐标:{0};笛卡尔坐标:{1}", cartographic2, cartesian2); // 笛卡尔坐标转为地图坐标 Cartographic cartographic3 = earth.Shape.CartesianToCartographic(cartesian2); Console.WriteLine("笛卡尔坐标:{0};地图坐标:{1}", cartesian2, cartographic3); // 新坐标系绕原坐标系z轴旋转90度,原向量(1,0,0) var vector4 = new Cartesian(1, 0, 0); var rotation4 = new ElementaryRotation(AxisIndicator.Third, Trig.DegreesToRadians(90)); Cartesian newVector4 = new Matrix3By3(rotation4).Multiply(vector4); Console.WriteLine("旋转前:{0};旋转后:{1}", vector4, newVector4); // 欧拉旋转 var vector5 = new Cartesian(1, 0, 0); double angle = Trig.DegreesToRadians(90); var euler = new EulerSequence(angle, angle, angle, EulerSequenceIndicator.Euler321); Cartesian newVector5 = new Matrix3By3(euler).Multiply(vector5); Console.WriteLine("旋转前:{0};旋转后:{1}", vector5, newVector5); // 偏航俯仰翻滚旋转 var vector6 = new Cartesian(1, 0, 0); double angle6 = Trig.DegreesToRadians(90); var ypr = new YawPitchRoll(angle, angle, angle, YawPitchRollIndicator.YPR); Cartesian newVector6 = new Matrix3By3(ypr).Multiply(vector6); Console.WriteLine("旋转前:{0};旋转后:{1}", vector6, newVector6); Console.Read(); }
static void Main(string[] args) { // 显示版本号 Console.WriteLine("DisplayVersion: {0}", StkComponentsCore.DisplayVersion); Console.WriteLine("Version: {0}", StkComponentsCore.Version); // 显示当前时刻地球质心和月球质心之间的距离 DateTime now = DateTime.Now; EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; MoonCentralBody moon = CentralBodiesFacet.GetFromContext().Moon; var vector = new VectorTrueDisplacement(earth.CenterOfMassPoint, moon.CenterOfMassPoint); double distance = vector.GetEvaluator().Evaluate(new JulianDate(now)).Magnitude; Console.WriteLine("当前时间:{0:yyyy-MM-dd HH:mm:ss.fff},当前日月距离:{1:0.000}千米", now, distance / 1000); Console.Read(); }
private static void Main() { // startup data configuration // Update LeapSecond.dat, and use it in the current calculation context. LeapSecondsFacetHelper.GetLeapSeconds().UseInCurrentContext(); EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; // Load EOP Data - For fixed to inertial transformations earth.OrientationParameters = EarthOrientationParametersHelper.GetEarthOrientationParameters(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Main()); }
/// <summary> /// Creates all objects in the demonstration. /// </summary> /// <param name="satelliteIdentifier">The NORAD identifier for the satellite to propagate.</param> public CesiumDemo(string satelliteIdentifier) { m_satelliteIdentifier = satelliteIdentifier; m_earth = CentralBodiesFacet.GetFromContext().Earth; // Create all objects for our scenario. // Each of these helper methods create some of the objects // which are stored in fields. // The work is divided up across methods to make the code easier to follow. CreateSatellite(); CreateFacility(); CreateSatelliteAccessLink(); CreateFacilitySensor(); CreateSensorDome(); CreateAzimuthElevationMask(); CreateAircraft(); }
public Main() { InitializeComponent(); var earth = CentralBodiesFacet.GetFromContext().Earth; // Load the GPS satellites from the almanac, including transmitters for specific block types, // using the data from the GPSData.txt file. m_gpsConstellation = GetGpsCommunicationsConstellation(); // create the receiver using a standard setup m_receiver = new GpsReceiver { NumberOfChannels = 12, ReceiverSolutionType = GpsReceiverSolutionType.AllInView, NavigationSatellites = m_gpsConstellation }; m_receiver.ReceiverConstraints.Add(new ElevationAngleConstraint(Trig.DegreesToRadians(5.0))); m_location = new PointCartographic(earth, new Cartographic(Trig.DegreesToRadians(-107.494000), Trig.DegreesToRadians(30.228800), 0)); m_orientation = new AxesEastNorthUp(earth, m_location); }
/// <summary> /// Finds the first time in a given interval that a given location is in sunlight. /// This is used in multiple demos to set the animation time. /// </summary> /// <param name="target">The target location to view in sunlight.</param> /// <param name="consideredInterval">The interval to consider.</param> /// <returns> /// The first time within the given date range where the target location is in sunlight, /// or the start of the given interval if it is never in sunlight. /// </returns> public static JulianDate ViewPointInSunlight(Point target, TimeInterval consideredInterval) { var earth = CentralBodiesFacet.GetFromContext().Earth; var sun = CentralBodiesFacet.GetFromContext().Sun; var sunlight = new LinkSpeedOfLight(sun, target, earth.InertialFrame); var sunlightConstraint = new CentralBodyObstructionConstraint(sunlight, earth); // The target is in sunlight when the sunlight link is not obstructed by the Earth. using (var accessEvaluator = sunlightConstraint.GetEvaluator(target)) { var accessResult = accessEvaluator.Evaluate(consideredInterval); var satisfactionIntervals = accessResult.SatisfactionIntervals; if (satisfactionIntervals.IsEmpty) { // No valid times (unlikely). Just use the start date. return(consideredInterval.Start); } return(satisfactionIntervals.Start); } }
/// <summary> /// Handles updating the various central body lists if the primary central body changes. /// </summary> /// <param name="sender">What fired this event.</param> /// <param name="e">Additional information about this event.</param> private void OnPrimaryCBSelectedIndexChanged(object sender, EventArgs e) { if (m_primaryCB.SelectedItem.ToString() != m_lastCB) { m_thirdBodies.Items.Remove(m_primaryCB.SelectedItem.ToString()); m_thirdBodies.Items.Add(m_lastCB); m_lastCB = m_primaryCB.SelectedItem.ToString(); if (m_primaryCB.SelectedItem.ToString() != EARTH) { // we only have drag models for the earth m_lastDragChecked = m_useDrag.Checked; m_useDrag.Checked = false; m_useDrag.Enabled = false; } else { m_useDrag.Checked = m_lastDragChecked; m_useDrag.Enabled = true; } CurrentCentralBodysGravitationalParameter = m_gravConstants[m_primaryCB.SelectedItem.ToString()]; CurrentCentralBody = CentralBodiesFacet.GetFromContext().GetByName(m_primaryCB.SelectedItem.ToString()); } }
private static void Main() { // startup data configuration // Update LeapSecond.dat, and use it in the current calculation context. LeapSecondsFacetHelper.GetLeapSeconds().UseInCurrentContext(); EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; // Load EOP Data - For fixed to inertial transformations earth.OrientationParameters = EarthOrientationParametersHelper.GetEarthOrientationParameters(); // Load JPL data // Optional - Without this an analytic model is used to position central bodies string dataPath = Path.Combine(Application.StartupPath, "Data"); JplDE430 jpl = new JplDE430(Path.Combine(dataPath, "plneph.430")); jpl.UseForCentralBodyPositions(CentralBodiesFacet.GetFromContext()); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new LotsOfSatellites()); }
/// <summary> /// Reset the camera to the home view. /// </summary> public void Home() { var earth = CentralBodiesFacet.GetFromContext().Earth; m_insight3D.Scene.Camera.ViewCentralBody(earth, earth.InertialFrame.Axes); }
private void OnLoad(object sender, EventArgs e) { // Create overlay toolbar and panels m_overlayToolbar = new OverlayToolbar(m_insight3D); m_overlayToolbar.Overlay.Origin = ScreenOverlayOrigin.BottomCenter; // Add additional toolbar buttons // Number of Satellites Button m_overlayToolbar.AddButton(GetDataFilePath("Textures/OverlayToolbar/manysatellites.png"), GetDataFilePath("Textures/OverlayToolbar/fewsatellites.png"), ToggleNumberOfSatellites); // Show/Hide Access Button m_overlayToolbar.AddButton(GetDataFilePath("Textures/OverlayToolbar/noshowaccess.png"), GetDataFilePath("Textures/OverlayToolbar/showaccess.png"), ToggleComputeAccess); // Initialize the text panel m_textPanel = new TextureScreenOverlay(0, 0, 80, 35) { Origin = ScreenOverlayOrigin.TopRight, BorderSize = 2, BorderColor = Color.Transparent, BorderTranslucency = 0.6f, Color = Color.Transparent, Translucency = 0.4f }; SceneManager.ScreenOverlays.Add(m_textPanel); // Show label for the moon Scene scene = m_insight3D.Scene; scene.CentralBodies[CentralBodiesFacet.GetFromContext().Moon].ShowLabel = true; // Create a marker primitive for the facility at Bells Beach Australia EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; Cartographic facilityPosition = new Cartographic(Trig.DegreesToRadians(144.2829), Trig.DegreesToRadians(-38.3697), 0.0); Texture2D facilityTexture = SceneManager.Textures.FromUri(GetDataFilePath(@"Markers\Facility.png")); MarkerBatchPrimitive marker = new MarkerBatchPrimitive(SetHint.Infrequent) { Texture = facilityTexture }; marker.Set(new[] { earth.Shape.CartographicToCartesian(facilityPosition) }); SceneManager.Primitives.Add(marker); PointCartographic point = new PointCartographic(earth, facilityPosition); Axes topographic = new AxesNorthEastDown(earth, point); ReferenceFrame facilityTopo = new ReferenceFrame(point, topographic); m_fixedToFacilityTopoEvaluator = GeometryTransformer.GetReferenceFrameTransformation(earth.FixedFrame, facilityTopo); Axes temeAxes = earth.TrueEquatorMeanEquinoxFrame.Axes; m_temeToFixedEvaluator = GeometryTransformer.GetAxesTransformation(temeAxes, earth.FixedFrame.Axes); m_showAccess = true; m_satellites = new Satellites(); CreateSatellites("stkSatDb"); // This Render() is needed so that the stars will show. scene.Render(); }
/// <summary> /// This will configure the entered point with all of the force models as entered in the GUI. /// </summary> /// <param name="point">The point to add the force models too.</param> /// <param name="area">The Scalar representing the area that the SRP and Drag model will see.</param> public void SetForceModelsOnPoint(PropagationNewtonianPoint point, Scalar area) { point.AppliedForces.Clear(); if (m_useSRP.Checked) { SimpleSolarRadiationForce srp = new SimpleSolarRadiationForce(point.IntegrationPoint, double.Parse(m_reflectivity.Text), area); if (m_shadowModel.SelectedItem.ToString() == DUALCONE) { srp.OccultationFactor = new ScalarOccultationDualCone(CentralBodiesFacet.GetFromContext().Sun, point.IntegrationPoint); } else if (m_shadowModel.SelectedItem.ToString() == CYLINDRICAL) { srp.OccultationFactor = new ScalarOccultationCylindrical(CentralBodiesFacet.GetFromContext().Sun, point.IntegrationPoint); } foreach (string id in m_eclipsingBodies.CheckedItems) { srp.OccultationFactor.OccludingBodies.Add(CentralBodiesFacet.GetFromContext().GetByName(id)); } point.AppliedForces.Add(srp); } if (m_useDrag.Checked) { ScalarAtmosphericDensity density = null; SolarGeophysicalData geoData = new ConstantSolarGeophysicalData(double.Parse(m_averageSolarFlux.Text), double.Parse(m_solarFlux.Text), double.Parse(m_kp.Text)); if (m_densityModel.SelectedItem.ToString() == JR) { density = new ScalarDensityJacchiaRoberts(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS86) { density = new ScalarDensityMsis86(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS90) { density = new ScalarDensityMsis90(point.IntegrationPoint, geoData); } else if (m_densityModel.SelectedItem.ToString() == MSIS2000) { density = new ScalarDensityMsis2000(point.IntegrationPoint, geoData); } AtmosphericDragForce atmo = new AtmosphericDragForce(density, new ScalarFixed(double.Parse(m_dragCoeff.Text)), area); point.AppliedForces.Add(atmo); } ThirdBodyGravity thirdGravity = new ThirdBodyGravity(point.IntegrationPoint); foreach (string item in m_thirdBodies.CheckedItems) { if (item == EARTH || item == SUN || item == MOON) { thirdGravity.AddThirdBody(item, CentralBodiesFacet.GetFromContext().GetByName(item).CenterOfMassPoint, m_gravConstants[item]); } else { thirdGravity.AddThirdBody(item, m_jplInfo.GetCenterOfMassPoint(m_nameToJplMapping[item]), m_gravConstants[item]); } } thirdGravity.CentralBody = CentralBodiesFacet.GetFromContext().GetByName(m_primaryCB.SelectedItem.ToString()); if (thirdGravity.ThirdBodies.Count > 0) { point.AppliedForces.Add(thirdGravity); } // Primary gravity string primaryCB = m_primaryCB.SelectedItem.ToString(); if (m_twoBody.Checked) { TwoBodyGravity gravity = new TwoBodyGravity(point.IntegrationPoint, CentralBodiesFacet.GetFromContext().GetByName(primaryCB), m_gravConstants[primaryCB]); point.AppliedForces.Add(gravity); } else { SphericalHarmonicsTideType tideType = SphericalHarmonicsTideType.None; if (m_tides.SelectedItem.ToString() == NOTIDES) { tideType = SphericalHarmonicsTideType.None; } else if (m_tides.SelectedItem.ToString() == PERMANENTTIDES) { tideType = SphericalHarmonicsTideType.PermanentTideOnly; } int order = int.Parse(m_order.Text); int degree = int.Parse(m_degree.Text); SphericalHarmonicGravityModel model = SphericalHarmonicGravityModel.ReadFrom(m_gravFile.Text); SphericalHarmonicGravity gravity = new SphericalHarmonicGravity(point.IntegrationPoint, new SphericalHarmonicGravityField(model, degree, order, true, tideType)); point.AppliedForces.Add(gravity); if (gravity.GravityField.CentralBody.Name != primaryCB) { throw new InvalidDataException("The central body you have selected does not match the central body in the gravity file."); } } if (primaryCB == EARTH) { point.IntegrationFrame = CentralBodiesFacet.GetFromContext().Earth.InternationalCelestialReferenceFrame; } else if (primaryCB == MOON) { point.IntegrationFrame = CentralBodiesFacet.GetFromContext().Moon.InertialFrame; } }
static Main() { // Load data for central bodies besides the earth, moon, and sun. s_jplData = new JplDE430(Path.Combine(DataPath, "plneph.430")); s_jplData.UseForCentralBodyPositions(CentralBodiesFacet.GetFromContext()); }
/// <summary> /// Construct a default instance. /// </summary> public Main() { InitializeComponent(); m_insight3D = new Insight3D(); m_insight3D.Dock = DockStyle.Fill; m_insight3DPanel.Controls.Add(m_insight3D); m_defaultStart = GregorianDate.Now; m_defaultEnd = m_defaultStart.AddDays(1); m_animation = new SimulationAnimation(); SceneManager.Animation = m_animation; m_display = new ServiceProviderDisplay(); m_forceModelSettings = new ForceModelSettings(s_jplData, GetDataFilePath("EarthGravityFile_EGM2008.grv")); m_integratorSettings = new IntegratorSettings(); m_area.Text = "20"; m_mass.Text = "500"; // Create overlay toolbar and panels m_overlayToolbar = new OverlayToolbar(m_insight3D); m_overlayToolbar.Overlay.Origin = ScreenOverlayOrigin.BottomCenter; // Initialize the text panel TextureScreenOverlay textPanel = new TextureScreenOverlay(0, 0, 220, 35) { Origin = ScreenOverlayOrigin.TopRight, BorderSize = 0, BorderColor = Color.Transparent, BorderTranslucency = 1.0f, Color = Color.Transparent, Translucency = 1.0f }; SceneManager.ScreenOverlays.Add(textPanel); m_dateTimeFont = new Font("Courier New", 12, FontStyle.Bold); Size textSize = Insight3DHelper.MeasureString(m_defaultStart.ToString(), m_dateTimeFont); m_textOverlay = new TextureScreenOverlay(0, 0, textSize.Width, textSize.Height) { Origin = ScreenOverlayOrigin.Center, BorderSize = 0 }; textPanel.Overlays.Add(m_textOverlay); // Show label for the moon m_insight3D.Scene.CentralBodies[CentralBodiesFacet.GetFromContext().Moon].ShowLabel = true; // Set the name for the element that will get propagated m_elementID = "Satellite"; // Subscribe to the time changed event SceneManager.TimeChanged += OnTimeChanged; // Set the start and stop times m_start.CustomFormat = DateFormat; m_end.CustomFormat = DateFormat; m_start.Text = m_defaultStart.ToString(DateFormat); m_end.Text = m_defaultEnd.ToString(DateFormat); m_animation.Time = m_defaultStart.ToJulianDate(); m_animation.StartTime = m_defaultStart.ToJulianDate(); m_animation.EndTime = m_defaultEnd.ToJulianDate(); // Dynamically set the camera's position and direction so that the camera will always be pointed at the daylit portion of the earth. EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; SunCentralBody sun = CentralBodiesFacet.GetFromContext().Sun; VectorTrueDisplacement earthToSunVector = new VectorTrueDisplacement(earth.CenterOfMassPoint, sun.CenterOfMassPoint); VectorEvaluator earthToSunEvaluator = earthToSunVector.GetEvaluator(); Cartesian earthToSunCartesian = earthToSunEvaluator.Evaluate(new JulianDate(m_defaultStart)); UnitCartesian earthToSunUnitCartesian = new UnitCartesian(earthToSunCartesian); UnitCartesian cameraDirection = new UnitCartesian(earthToSunUnitCartesian.Invert()); Cartesian cameraPosition = new Cartesian(earthToSunUnitCartesian.X * 50000000, earthToSunUnitCartesian.Y * 50000000, earthToSunUnitCartesian.Z * 50000000); m_insight3D.Scene.Camera.Position = cameraPosition; m_insight3D.Scene.Camera.Direction = cameraDirection; }
public Main() { InitializeComponent(); m_insight3D = new Insight3D(); m_insight3D.Dock = DockStyle.Fill; m_insight3DPanel.Controls.Add(m_insight3D); // We don't have a call placed yet. m_hangUpButton.Enabled = false; m_callPlaced = false; // Load a texture which we will use for our phone locations. m_phoneTexture = SceneManager.Textures.FromUri(Path.Combine(Application.StartupPath, "Data/Markers/facility.png")); // Create a ServiceProviderDisplay to be used for visualization. m_display = new ServiceProviderDisplay(); // Create the font to use for labeling. We are using the same font as the control, only smaller. m_labelFont = new Font(Font.FontFamily, 10, Font.Style, Font.Unit, Font.GdiCharSet, Font.GdiVerticalFont); // The call will be taking place at a frequency of 1620.5e6. m_intendedSignal = new IntendedSignalByFrequency(1620.5e6); // Create the transmitting phone that we will use for our call and add it to the display. m_transmittingPhone = CreateTransmittingPhone(); m_display.ServiceProviders.Add(m_transmittingPhone); // Do the same for the receiving phone. m_receivingPhone = CreateReceivingPhone(); m_display.ServiceProviders.Add(m_receivingPhone); // Create an instance of IridiumSatellite for each of the three satellites we will // be using and add them to the display. // IridiumSatellite is a Platform-based class that adds default graphics and a // Transceiver object for communication. var analysisDate = new JulianDate(new GregorianDate(2011, 8, 2, 18, 1, 0)); var iridium49Tles = TwoLineElementSetHelper.GetTles("25108", analysisDate); var iridium49 = new IridiumSatellite("Iridium 49", iridium49Tles, m_labelFont, m_intendedSignal.TargetFrequency); m_display.ServiceProviders.Add(iridium49); var iridium58Tles = TwoLineElementSetHelper.GetTles("25274", analysisDate); var iridium58 = new IridiumSatellite("Iridium 58", iridium58Tles, m_labelFont, m_intendedSignal.TargetFrequency); m_display.ServiceProviders.Add(iridium58); var iridium4Tles = TwoLineElementSetHelper.GetTles("24796", analysisDate); var iridium4 = new IridiumSatellite("Iridium 4", iridium4Tles, m_labelFont, m_intendedSignal.TargetFrequency); m_display.ServiceProviders.Add(iridium4); // If the TLE epoch is too far from our expected analysis date, then we are // offline and loading cached data. Adjust the analysis date to match. if (iridium49Tles[0].Epoch.DaysDifference(analysisDate) > 5) { analysisDate = iridium49Tles[0].Epoch; } // Iridium 49 will be the receiving end of our caller's "uplink". // Modify the receiving antenna to be isotropic. iridium49.Transceiver.InputAntennaGainPattern = new IsotropicGainPattern(); // Iridium 4 will be the transmitting end of our call receiver's "downlink". // Modify the transmitting antenna to be isotropic. iridium4.Transceiver.OutputAntennaGainPattern = new IsotropicGainPattern(); // Now that we've created all of our definition objects, we need to build // the links between them that make up our communication system. m_communicationSystem = new CommunicationSystem(); // Add a link for each hop in the chain. // This could have been accomplished with a single call to AddChain. // However, since we plan on further configuring each of the individual links // generated for us, we add them one at a time. var linkCollection = m_communicationSystem.Links; m_callerToIridium49UpLink = linkCollection.Add("Uplink to Iridium 49", m_transmittingPhone, iridium49.Transceiver); m_iridium49To58Crosslink = linkCollection.Add("Iridium 49 -> Iridium 58", iridium49.Transceiver, iridium58.Transceiver); m_iridium58To4Crosslink = linkCollection.Add("Iridium 58 -> Iridium 4", iridium58.Transceiver, iridium4.Transceiver); m_iridium4ToReceiverDownLink = linkCollection.Add("Downlink from Iridium 4", iridium4.Transceiver, m_receivingPhone); // Now that we have the links, we can add an AccessConstraintsExtension to them so // that each link is only valid if they have line of sight to each other. var earth = CentralBodiesFacet.GetFromContext().Earth; var callerToIridium49Constraint = new CentralBodyObstructionConstraint(m_callerToIridium49UpLink, earth); m_callerToIridium49UpLink.Extensions.Add(new AccessConstraintsExtension(callerToIridium49Constraint)); var iridium49To58Constraint = new CentralBodyObstructionConstraint(m_iridium49To58Crosslink, earth); m_iridium49To58Crosslink.Extensions.Add(new AccessConstraintsExtension(iridium49To58Constraint)); var iridium58To4Constraint = new CentralBodyObstructionConstraint(m_iridium58To4Crosslink, earth); m_iridium58To4Crosslink.Extensions.Add(new AccessConstraintsExtension(iridium58To4Constraint)); var iridium4ToReceiverConstraint = new CentralBodyObstructionConstraint(m_iridium4ToReceiverDownLink, earth); m_iridium4ToReceiverDownLink.Extensions.Add(new AccessConstraintsExtension(iridium4ToReceiverConstraint)); m_linkComboBox.DisplayMember = "Name"; m_linkComboBox.Items.Add(m_callerToIridium49UpLink); m_linkComboBox.Items.Add(m_iridium49To58Crosslink); m_linkComboBox.Items.Add(m_iridium58To4Crosslink); m_linkComboBox.Items.Add(m_iridium4ToReceiverDownLink); m_linkComboBox.SelectedItem = m_iridium4ToReceiverDownLink; // Even though we haven't added any link graphics yet, we will later, so add them // to the display now. m_display.ServiceProviders.Add(m_callerToIridium49UpLink); m_display.ServiceProviders.Add(m_iridium49To58Crosslink); m_display.ServiceProviders.Add(m_iridium58To4Crosslink); m_display.ServiceProviders.Add(m_iridium4ToReceiverDownLink); // While we have set the location for our two phones and the satellite // transceivers, what we haven't done is assign their orientations. This can be // done automatically using the ConfigureAntennaTargeting method. Note that // ConfigureAntennaTargeting is a best effort method and returns status information // in regards to any problems it encounters. We don't check them here // simply because we know it will succeed. m_communicationSystem.ConfigureAntennaTargeting(); // Now that our initial configuration is complete, make sure we call ApplyChanges // on the display so that the visualization is created. m_display.ApplyChanges(); // Update the display to the current time. m_display.Update(SceneManager.Time); // Set up the animation time for our call. var animation = new SimulationAnimation { StartTime = analysisDate, EndTime = analysisDate.AddMinutes(15.0), TimeStep = Duration.FromSeconds(0.5), StartCycle = SimulationAnimationCycle.Loop, EndCycle = SimulationAnimationCycle.Loop }; SceneManager.Animation = animation; // Subscribe to the time changed event so we can update our display. SceneManager.TimeChanged += SceneManagerTimeChanged; // Reset to the beginning. animation.Reset(); // Configure the animation toolbar that overlays the 3D view. OverlayToolbar animationToolbar = new OverlayToolbar(m_insight3D); animationToolbar.Overlay.Origin = ScreenOverlayOrigin.BottomCenter; // Zoom to a location that includes both the caller and receiver. m_insight3D.Scene.Camera.ViewExtent(earth, Trig.DegreesToRadians(39.6333), Trig.DegreesToRadians(11.1333), Trig.DegreesToRadians(77.5833), Trig.DegreesToRadians(12.9833)); // Move the camera further back so that all satellites are visible. m_insight3D.Scene.Camera.Distance += 5000000.0; // Turn off lighting since it's the middle of the night and we want to be able to see everything, m_insight3D.Scene.Lighting.Enabled = false; // Create our link budget overlay helper which will display // the complete link budget for a selected link on top of the display. m_linkBudgetOverlayHelper = new LinkBudgetOverlayHelper(m_labelFont); //Hide it until the call is initiated m_linkBudgetOverlayHelper.Overlay.Display = false; // Add the actual overlay to Insight3D SceneManager.ScreenOverlays.Add(m_linkBudgetOverlayHelper.Overlay); }
/// <summary> /// Constructs an instance with the entered properties. /// </summary> /// <param name="jplInfo">The JplDe info.</param> /// <param name="gravityFile">A file specifying the gravitational field for the primary /// central body.</param> public ForceModelSettings(JplDE jplInfo, string gravityFile) { InitializeComponent(); // adding all of the central body gravitational parameters. m_gravConstants.Add(JplDECentralBody.Earth.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Earth)); m_gravConstants.Add(JplDECentralBody.Sun.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Sun)); m_gravConstants.Add(JplDECentralBody.Moon.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Moon)); m_gravConstants.Add(JplDECentralBody.Jupiter.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Jupiter)); m_gravConstants.Add(JplDECentralBody.Mars.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Mars)); m_gravConstants.Add(JplDECentralBody.Mercury.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Mercury)); m_gravConstants.Add(JplDECentralBody.Neptune.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Neptune)); m_gravConstants.Add(JplDECentralBody.Pluto.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Pluto)); m_gravConstants.Add(JplDECentralBody.Saturn.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Saturn)); m_gravConstants.Add(JplDECentralBody.Uranus.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Uranus)); m_gravConstants.Add(JplDECentralBody.Venus.ToString(), jplInfo.GetGravitationalParameter(JplDECentralBody.Venus)); m_nameToJplMapping.Add(EARTH, JplDECentralBody.Earth); m_nameToJplMapping.Add(SUN, JplDECentralBody.Sun); m_nameToJplMapping.Add(MOON, JplDECentralBody.Moon); m_nameToJplMapping.Add("Jupiter", JplDECentralBody.Jupiter); m_nameToJplMapping.Add("Mars", JplDECentralBody.Mars); m_nameToJplMapping.Add("Mercury", JplDECentralBody.Mercury); m_nameToJplMapping.Add("Neptune", JplDECentralBody.Neptune); m_nameToJplMapping.Add("Pluto", JplDECentralBody.Pluto); m_nameToJplMapping.Add("Saturn", JplDECentralBody.Saturn); m_nameToJplMapping.Add("Uranus", JplDECentralBody.Uranus); m_nameToJplMapping.Add("Venus", JplDECentralBody.Venus); m_jplInfo = jplInfo; // setting default non-spherical gravity parameters. m_degree.Text = 21.ToString(); m_order.Text = 21.ToString(); m_gravFile.Text = gravityFile; m_tides.Items.Add(PERMANENTTIDES); m_tides.Items.Add(NOTIDES); m_tides.SelectedIndex = 0; m_tides.DropDownStyle = ComboBoxStyle.DropDownList; // configuring primary central body list. m_primaryCB.Items.Add(CentralBodiesFacet.GetFromContext().Earth.Name); m_primaryCB.Items.Add(CentralBodiesFacet.GetFromContext().Moon.Name); m_primaryCB.DropDownStyle = ComboBoxStyle.DropDownList; m_lastCB = EARTH; CurrentCentralBody = CentralBodiesFacet.GetFromContext().Earth; m_primaryCB.SelectedItem = EARTH; // adding all of the possible third bodies foreach (KeyValuePair <string, double> pair in m_gravConstants) { string name = pair.Key; if (!m_thirdBodies.Items.Contains(name) && name != CurrentCentralBody.Name) { m_thirdBodies.Items.Add(name); } } m_thirdBodies.Items.Remove(EARTH); // setting the default Solar Radiation Pressure properties m_useSRP.Checked = true; foreach (CentralBody body in CentralBodiesFacet.GetFromContext()) { if (body.Name == EARTH || body.Name == SUN || body.Name == MOON) { m_eclipsingBodies.Items.Add(body.Name, true); } } m_eclipsingBodies.Items.Remove(SUN); m_shadowModel.Items.Add(DUALCONE); m_shadowModel.Items.Add(CYLINDRICAL); m_shadowModel.SelectedIndex = 0; m_shadowModel.DropDownStyle = ComboBoxStyle.DropDownList; m_reflectivity.Text = (1.0).ToString(); // setting the default drag properties m_useDrag.Checked = true; m_densityModel.Items.Add(JR); m_densityModel.Items.Add(MSIS86); m_densityModel.Items.Add(MSIS90); m_densityModel.Items.Add(MSIS2000); m_densityModel.SelectedIndex = 0; m_densityModel.DropDownStyle = ComboBoxStyle.DropDownList; m_dragCoeff.Text = (2.2).ToString(); m_kp.Text = (3.0).ToString(); m_solarFlux.Text = (150).ToString(); m_averageSolarFlux.Text = (150).ToString(); }
/// <summary> /// Method to calculate all the data required for the graphs. /// </summary> private void OnAddReceiverClick(object sender, EventArgs e) { #region CreateAndConfigureReceiver // Let's create the GPSReceiver. The receiver stores many properties and has a defined location. This location // is the point of reference for visibility calculations. receiver = new GpsReceiver(); // add receiver to the tree TreeNode newNode = new TreeNode(Localization.Receiver); rootNode.Nodes.Add(newNode); // Easy reference to Earth Central body used to initialize the ElevationAngleAccessConstraint and // to calculate the Az/El/Range Data. EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth; // set the receiver properties based on user selections // The receiver has a receiver FrontEnd that contains the visibility and tracking constraints // Be sure to convert your angles to Radians! double minimumAngle = Trig.DegreesToRadians(Double.Parse(MaskAngle.Text)); receiver.ReceiverConstraints.Clear(); receiver.ReceiverConstraints.Add(new ElevationAngleConstraint(earth, minimumAngle)); receiver.NumberOfChannels = (int)NumberOfChannels.Value; receiver.NoiseModel = new ConstantGpsReceiverNoiseModel(0.8); // The receiver's methods of reducing the number of visible satellites to the limit imposed by the number of channels if (BestNSolType.Checked) { receiver.ReceiverSolutionType = GpsReceiverSolutionType.BestN; } else { receiver.ReceiverSolutionType = GpsReceiverSolutionType.AllInView; } // create a new location for the receiver by using the Cartographic type from AGI.Foundation.Coordinates // again, remember to convert from degrees to Radians! (except the height of course) Cartographic position = new Cartographic(Trig.DegreesToRadians(double.Parse(Longitude.Text)), Trig.DegreesToRadians(double.Parse(Latitude.Text)), double.Parse(ReceiverHeight.Text)); // Now create an antenna for the GPS receiver. We specify the location of the antenna by assigning a // PointCartographic instance to the LocationPoint property. We specify that the antenna should be oriented // according to the typically-used East-North-Up axes by assigning an instance of AxesEastNorthUp to // the OrientationAxes property. While the orientation of the antenna won't affect which satellites are visible // or tracked in this case, it will affect the DOP values. For example, the EDOP value can be found in // DilutionOfPrecision.X, but only if we've configured the antenna to use East-North-Up axes. PointCartographic antennaLocationPoint = new PointCartographic(earth, position); Platform antenna = new Platform { LocationPoint = antennaLocationPoint, OrientationAxes = new AxesEastNorthUp(earth, antennaLocationPoint) }; receiver.Antenna = antenna; #endregion // update the tree to reflect the correct receiver info newNode.Nodes.Add(new TreeNode(string.Format(Localization.FixedMaskAngle + "= {0:0.00} " + Localization.degrees, MaskAngle.Text))); newNode.Nodes.Add(new TreeNode(string.Format(Localization.NumberOfChannels + "= {0}", NumberOfChannels.Value))); newNode.Nodes.Add(new TreeNode(string.Format(Localization.SolutionType + "= {0}", receiver.ReceiverSolutionType == GpsReceiverSolutionType.AllInView ? Localization.AllInView : Localization.BestN))); newNode.Nodes.Add(new TreeNode(string.Format(Localization.Latitude + "= {0:0.000000} " + Localization.degrees, Latitude.Text))); newNode.Nodes.Add(new TreeNode(string.Format(Localization.Longitude + "= {0:0.000000} " + Localization.degrees, Longitude.Text))); newNode.Nodes.Add(new TreeNode(string.Format(Localization.Height + "= {0:0.000} " + Localization.meters, ReceiverHeight.Text))); rootNode.Expand(); newNode.Expand(); #region CalculateDataForGraphs // Now, we'll open the almanac SemAlmanac almanac; using (Stream stream = openAlmanacDialog.OpenFile()) using (StreamReader reader = new StreamReader(stream)) { // Read the SEM almanac from an almanac stream reader. almanac = SemAlmanac.ReadFrom(reader, 1); } // Now create a PlatformCollection to hold GpsSatellite object instances. The SemAlmanac method CreateSatellitesFromRecords returns // just such a collection. We'll use this set of satellites as the set from which we'll try and track. There is a // GpsSatellite object for each satellite specified in the almanac. PlatformCollection gpsSatellites = almanac.CreateSatelliteCollection(); // We provide the receiver with the complete set of gpsSatellites to consider for visibility calculations. // This is usually all SVs defined in the almanac - however you may want to remove SVs that aren't healthy. This can // be done by creating the gpsSatellites collection above using another version of the CreateSatellitesFromRecords method that // takes a SatelliteOutageFileReader. receiver.NavigationSatellites = gpsSatellites; // Optimization opportunity: Add the following code in a thread. This will help for long duration analyses. // Now that we have the receiver and location setup, we need to evaluate all the pertinent data. // using a SatelliteTrackingEvaluator, we can track satellites and using a DOP Evaluator, // we can calculate DOP at a specified time. // The receiver's GetSatelliteTrackingEvaluator method will provide a SatelliteTrackingEvaluator for you. // Similarly, the GetDilutionOfPrecisionEvaluator provides the DOP evaluator. // We create all evaluators in the same EvaluatorGroup for the best performance. EvaluatorGroup group = new EvaluatorGroup(); Evaluator <int[]> satTrackingEvaluator = receiver.GetSatelliteTrackingIndexEvaluator(group); Evaluator <DilutionOfPrecision> dopEvaluator = receiver.GetDilutionOfPrecisionEvaluator(group); // We also need to create an evaluator to compute Azimuth/Elevation for each of the SVs MotionEvaluator <AzimuthElevationRange>[] aerEvaluators = new MotionEvaluator <AzimuthElevationRange> [gpsSatellites.Count]; for (int i = 0; i < gpsSatellites.Count; ++i) { Platform satellite = receiver.NavigationSatellites[i]; VectorTrueDisplacement vector = new VectorTrueDisplacement(antenna.LocationPoint, satellite.LocationPoint); aerEvaluators[i] = earth.GetAzimuthElevationRangeEvaluator(vector, group); } // First we'll initialize the data structures used to plot the data for (int i = 0; i < DOPData.Length; i++) { // PointPairList is defined in the ZedGraph reference DOPData[i] = new PointPairList(); } // We need to know which time standard to use here. If the user has specified that GPS time is to be used // we need to create the JulianDates with the GlobalPositioningSystemTime standard. if (GPSTimeRadio.Checked) { startjd = new JulianDate(StartTime.Value, TimeStandard.GlobalPositioningSystemTime); stopjd = new JulianDate(StopTime.Value, TimeStandard.GlobalPositioningSystemTime); } else { // otherwise, the default time standard is UTC startjd = new JulianDate(StartTime.Value); stopjd = new JulianDate(StopTime.Value); } // Now we''ll create the variables we'll need for iterating through time. // The propagator requires a Duration type be used to specify the timestep. Duration dur = stopjd - startjd; double timestep = Double.Parse(TimeStep.Text); // Initialize the progressbar with appropriate values progressBar1.Maximum = (int)dur.TotalSeconds; progressBar1.Step = (int)timestep; // now we'll iterate through time by adding seconds to the start time JulianDate // creating a new JulianDate 'evaluateTime' each time step. for (double t = 0; t <= dur.TotalSeconds; t += timestep) { JulianDate evaluateTime = startjd.AddSeconds(t); // The string 'trackedSVs' is the start of a string we'll continue to build through this time // iteration. It will contain the info we'll need to put in the DOP graph tooltips for the different // DOP series (VDOP, HDOP, etc.) String trackedSVs = Localization.Tracked + ": "; // The evaluator method GetTrackedSatellites will take the current time and the initial list of satellites and // determine which satellites can be tracked based on the receiver constraints setup earlier. This method // returns a PlatformCollection object as well (though we'll cast each member of the Collection to a GPSSatellite type) int[] trackedSatellites = satTrackingEvaluator.Evaluate(evaluateTime); foreach (int satelliteIndex in trackedSatellites) { Platform satellite = receiver.NavigationSatellites[satelliteIndex]; // Now we have access to a Platform object representing a GPS satellite and calculate the azimuth and elevation // of each. Note that we're just calculating the azimuth and elevation, but could just as easily get the // range as well. AzimuthElevationRange aer = aerEvaluators[satelliteIndex].Evaluate(evaluateTime); // Get the GpsSatelliteExtension attached to the platform. The extension extends a // platform with GPS-specific information. In this case, we need the // satellites PRN. GpsSatelliteExtension extension = satellite.Extensions.GetByType <GpsSatelliteExtension>(); // Create two separate PointPairLists to hold the data stored by Time and Azimuth PointPairList thisTimePointList, thisAzPointList; // Before we can arbitrarily create new PointPair Lists, we have to see if the Data Storage structures already contain a list // for this PRN. // The variables AzElData_TimeBased and AzElData_AzimuthBased are dictionaries that hold the PointPairLists using the PRN // as a key. We use this structure to store a large amount of data for every satellite in a single, easy to access, variable. // if the satellite we're currently looking at already has a list defined in the dictionary, we'll use that one, otherwise // we'll create a new list if (AzElData_TimeBased.ContainsKey(extension.PseudoRandomNumber)) { thisTimePointList = AzElData_TimeBased[extension.PseudoRandomNumber]; AzElData_TimeBased.Remove(extension.PseudoRandomNumber); } else { thisTimePointList = new PointPairList(); } if (AzElData_AzimuthBased.ContainsKey(extension.PseudoRandomNumber)) { thisAzPointList = AzElData_AzimuthBased[extension.PseudoRandomNumber]; AzElData_AzimuthBased.Remove(extension.PseudoRandomNumber); } else { thisAzPointList = new PointPairList(); } // Now to get the actual Azimuth and elevation data // Converting your Radians to degrees here makes the data appear in a more readable format. We also constrain the azimuth // to be within the interval [0, 2*pi] double azimuth = Trig.RadiansToDegrees(Trig.ZeroToTwoPi(aer.Azimuth)); double elevation = Trig.RadiansToDegrees(aer.Elevation); #endregion // now create the point for the Azimuth based data PointPair thisAzPoint = new PointPair(azimuth, elevation); // and add the tooltip (ZedGraph uses the Tag property on a PointPair for the tooltip on that datapoint ) thisAzPoint.Tag = String.Format("PRN {0}, {1}, " + Localization.Az + ": {2:0.000}, " + Localization.El + ": {3:0.000}", extension.PseudoRandomNumber, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), azimuth, elevation); // and finally add this point to the list thisAzPointList.Add(thisAzPoint); // now we'll do the same for the time-based data, instead of adding the Az and El, we'll add the time and El. // Create a new XDate object to store the time for this point double txd = (double)new XDate(evaluateTime.ToDateTime()); // add the time and elevation data to this point PointPair thisTimePoint = new PointPair(txd, Trig.RadiansToDegrees(aer.Elevation)); // Create the tooltip tag thisTimePoint.Tag = String.Format("PRN {0}, {1}, " + Localization.Az + ": {2:0.000}, " + Localization.El + ": {3:0.000}", extension.PseudoRandomNumber, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), azimuth, elevation); // finally add this point to the list thisTimePointList.Add(thisTimePoint); //Now that this data is all calculated, we'll add the point lists to the correct data structures for the GpsSatellite we're working with AzElData_TimeBased.Add(extension.PseudoRandomNumber, thisTimePointList); AzElData_AzimuthBased.Add(extension.PseudoRandomNumber, thisAzPointList); // now update the 'trackedSVs' string to be used for the DOP data tooltip // wee need to do this inside the GpsSatellite loop because we need to get the entire list of tracked SVs for this time step. // we won't use this string until we're out of the loop however. trackedSVs += extension.PseudoRandomNumber.ToString() + ", "; } // now we're out of the GpsSatellite loop, we'll do some string manipulation to get the tooltip for the DOP data. // (gets rid of the last inserted comma) string svs = trackedSVs.Substring(0, trackedSVs.LastIndexOf(' ') - 1); try { // Now we use the evaluator to calculate the DilutionOfPrecision for us for this timestep DilutionOfPrecision dop = dopEvaluator.Evaluate(evaluateTime); // if the dop object throws an exception, there aren't enough tracked satellites to form a navigation solution (typically < 4 tracked) // in that case we leave the data for this time unfilled. The graph will then have empty spots for this time. // Here we create a new PointPair and a new XDate to add to the X-Axis PointPair pp; double txd = (double)new XDate(evaluateTime.ToDateTime()); // add the East DOP value and the time to the PointPair and set the tooltip tag property for this series. pp = new PointPair(txd, dop.X); pp.Tag = String.Format("{0}\n{1} " + Localization.EDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.X); // add the point to the 0th element of the DOPData structure DOPData[0].Add(pp); // repeat for North DOP pp = new PointPair(txd, dop.Y); pp.Tag = String.Format("{0}\n{1} " + Localization.NDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.Y); DOPData[1].Add(pp); // repeat for the Vertical DOP pp = new PointPair(txd, dop.Z); pp.Tag = String.Format("{0}\n{1} " + Localization.VDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.Z); DOPData[2].Add(pp); // repeat for the Horizontal DOP pp = new PointPair(txd, dop.XY); pp.Tag = String.Format("{0}\n{1} " + Localization.HDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.XY); DOPData[3].Add(pp); // repeat for the Position DOP pp = new PointPair(txd, dop.Position); pp.Tag = String.Format("{0}\n{1} " + Localization.PDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.Position); DOPData[4].Add(pp); // repeat for the Time DOP pp = new PointPair(txd, dop.Time); pp.Tag = String.Format("{0}\n{1} " + Localization.TDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.Time); DOPData[5].Add(pp); // repeat for the Geometric DOP pp = new PointPair(txd, dop.Geometric); pp.Tag = String.Format("{0}\n{1} " + Localization.GDOP + ": {2:0.000}", svs, evaluateTime.ToDateTime().ToString("M/d/yyyy, h:mm tt"), dop.Geometric); DOPData[6].Add(pp); // Notice here that the different DOP values (East, North, etc) were denoted by the dop.X, dop.Y etc. This is because the // DOP values could be in any coordinate system. In our case, we're in the ENU coordinate system an X represents East, Y // represents North, Z represents Vertical, XY represents horizontal. You can change the reference frame the DOP is reported in // but you will then have to understand that the dop.X value corresponds to your X-defined axis and so on. } catch { // Do Nothing here - we just won't add the data to the data list } // update the progress bar - we're done with this time step! progressBar1.PerformStep(); } // finally update the graphs UpdateDopGraph(); updateAzElGraph(); // reset the progress bar progressBar1.Value = 0; // and set the appropriate button states SetControlStates(true); }
/// <summary> /// Switch the camera to view the Moon. /// </summary> public void Moon() { var moon = CentralBodiesFacet.GetFromContext().Moon; m_insight3D.Scene.Camera.ViewCentralBody(moon, moon.InertialFrame.Axes); }
/// <summary> /// Creates a new instance with the provided properties. /// </summary> public IridiumSatellite(string name, IEnumerable <TwoLineElementSet> tles, Font font, double targetFrequency) { var earth = CentralBodiesFacet.GetFromContext().Earth; //Set the name and create the point from the TLE. Name = name; LocationPoint = new Sgp4Propagator(tles).CreatePoint(); OrientationAxes = new AxesVehicleVelocityLocalHorizontal(earth.InertialFrame, LocationPoint); //Create a transceiver modeled after Iridium specs. m_transceiver = new Transceiver { Name = Name + " Transceiver", Modulation = new ModulationQpsk(), OutputGain = 100.0, OutputNoiseFactor = 1.2, CarrierFrequency = targetFrequency, Filter = new RectangularFilter { Frequency = targetFrequency, UpperBandwidthLimit = 20.0e6, LowerBandwidthLimit = -20.0e6 }, InputAntennaGainPattern = new GaussianGainPattern(1.0, 0.55, 0.001), OutputAntennaGainPattern = new GaussianGainPattern(1.0, 0.55, 0.001) }; m_transceiver.InputAntenna.LocationPoint = new PointFixedOffset(ReferenceFrame, new Cartesian(0, -1.0, 0)); m_transceiver.OutputAntenna.LocationPoint = new PointFixedOffset(ReferenceFrame, new Cartesian(0, +1.0, 0)); // setup Marker graphics for the satellites var satelliteTexture = SceneManager.Textures.FromUri(Path.Combine(Application.StartupPath, "Data/Markers/smallsatellite.png")); m_markerGraphicsExtension = new MarkerGraphicsExtension(new MarkerGraphics { Texture = new ConstantGraphicsParameter <Texture2D>(satelliteTexture), DisplayParameters = new DisplayParameters { // hide marker when camera is closer than the below distance MinimumDistance = new ConstantGraphicsParameter <double>(17500000.0) } }); Extensions.Add(m_markerGraphicsExtension); // setup Model graphics for the satellites var modelUri = new Uri(Path.Combine(Application.StartupPath, "Data/Models/iridium.mdl")); m_modelGraphicsExtension = new ModelGraphicsExtension(new ModelGraphics { Uri = new ConstantGraphicsParameter <Uri>(modelUri), Scale = new ConstantGraphicsParameter <double>(50000.0), DisplayParameters = new DisplayParameters { // hide model when camera is further than the marker minimum distance above MaximumDistance = m_markerGraphicsExtension.MarkerGraphics.DisplayParameters.MinimumDistance } }); Extensions.Add(m_modelGraphicsExtension); // setup text graphics for the satellites m_textGraphicsExtension = new TextGraphicsExtension(new TextGraphics { Color = new ConstantGraphicsParameter <Color>(Color.Red), Font = new ConstantGraphicsParameter <Font>(font), Outline = new ConstantGraphicsParameter <bool>(true), OutlineColor = new ConstantGraphicsParameter <Color>(Color.Black), Text = new ConstantGraphicsParameter <string>(Name), Origin = new ConstantGraphicsParameter <Origin>(Origin.TopCenter), PixelOffset = new ConstantGraphicsParameter <PointF>(new PointF(0, -satelliteTexture.Template.Height / 2)) }); if (TextureFilter2D.Supported(TextureWrap.ClampToEdge)) { m_textGraphicsExtension.TextGraphics.TextureFilter = new ConstantGraphicsParameter <TextureFilter2D>(TextureFilter2D.NearestClampToEdge); } Extensions.Add(m_textGraphicsExtension); }
/// <summary> /// Create a Platform for the requested satellite using a TLE for position. /// The satellite will be visually represented by a labeled glTF model, /// the satellite's orbit will be shown, and vectors will be drawn for /// the body axes of the satellite, plus a vector indicating the direction /// of the sun. /// </summary> private void CreateSatellite() { // Get the current TLE for the given satellite identifier. var tleList = TwoLineElementSetHelper.GetTles(m_satelliteIdentifier, JulianDate.Now); // Use the epoch of the first TLE, since the TLE may have been loaded from offline data. m_epoch = tleList[0].Epoch; // Propagate the TLE and use that as the satellite's location point. var locationPoint = new Sgp4Propagator(tleList).CreatePoint(); m_satellite = new Platform { Name = "Satellite " + m_satelliteIdentifier, LocationPoint = locationPoint, // Orient the satellite using Vehicle Velocity Local Horizontal (VVLH) axes. OrientationAxes = new AxesVehicleVelocityLocalHorizontal(m_earth.FixedFrame, locationPoint), }; // Set the identifier for the satellite in the CZML document. m_satellite.Extensions.Add(new IdentifierExtension(m_satelliteIdentifier)); // Configure a glTF model for the satellite. m_satellite.Extensions.Add(new ModelGraphicsExtension(new ModelGraphics { // Link to a binary glTF file. Model = new CesiumResource(GetModelUri("satellite.glb"), CesiumResourceBehavior.LinkTo), // By default, Cesium plays all animations in the model simultaneously, which is not desirable. RunAnimations = false, })); // Configure a label for the satellite. m_satellite.Extensions.Add(new LabelGraphicsExtension(new LabelGraphics { // Use the name of the satellite as the text of the label. Text = m_satellite.Name, // Change the color of the label after 12 hours. This demonstrates specifying that // a value varies over time using intervals. FillColor = new TimeIntervalCollection <Color> { // Green for the first half day... new TimeInterval <Color>(JulianDate.MinValue, m_epoch.AddDays(0.5), Color.Green, true, false), // Red thereafter. new TimeInterval <Color>(m_epoch.AddDays(0.5), JulianDate.MaxValue, Color.Red, false, true), }, // Only show label when camera is far enough from the satellite, // to avoid visually clashing with the model. DistanceDisplayCondition = new Bounds(1000.0, double.MaxValue), })); // Configure graphical display of the orbital path of the satellite. m_satellite.Extensions.Add(new PathGraphicsExtension(new PathGraphics { // Configure the visual appearance of the line. Material = new PolylineOutlineMaterialGraphics { Color = Color.White, OutlineWidth = 1.0, OutlineColor = Color.Black, }, Width = 2.0, // Lead and Trail time indicate how much of the path to render. LeadTime = Duration.FromMinutes(44.0).TotalSeconds, TrailTime = Duration.FromMinutes(44.0).TotalSeconds, })); // Create vectors for the X, Y, and Z axes of the satellite. m_satelliteXAxis = CreateAxesVector(m_satellite, CartesianElement.X, Color.Green, "SatelliteX"); m_satelliteYAxis = CreateAxesVector(m_satellite, CartesianElement.Y, Color.Red, "SatelliteY"); m_satelliteZAxis = CreateAxesVector(m_satellite, CartesianElement.Z, Color.Blue, "SatelliteZ"); // Create a vector from the satellite to the Sun. // Compute the vector from the satellite's location to the Sun's center of mass. var sunCenterOfMassPoint = CentralBodiesFacet.GetFromContext().Sun.CenterOfMassPoint; var vectorSatelliteToSun = new VectorTrueDisplacement(m_satellite.LocationPoint, sunCenterOfMassPoint); // Create the visual vector. m_satelliteSunVector = new GraphicalVector { LocationPoint = m_satellite.LocationPoint, Vector = vectorSatelliteToSun, VectorGraphics = new VectorGraphics { Length = 5.0, Color = Color.Yellow, }, }; // Set the identifier for the vector in the CZML document. m_satelliteSunVector.Extensions.Add(new IdentifierExtension("SunVector")); // Orient the solar panels on the satellite model to point at the sun. var satelliteYVector = m_satellite.OrientationAxes.GetVectorElement(CartesianElement.Y); // allow only Z axis to rotate to follow sun vector. Constrain sun vector to Y, and satellite Y vector to X. var constrainedAxes = new AxesAlignedConstrained(satelliteYVector, AxisIndicator.First, vectorSatelliteToSun, AxisIndicator.Second); // Satellite axes are Vehicle Velocity Local Horizontal (VVLH) axes, where X is forward and Z is down, // but Cesium model axes are Z forward, Y up. So, create an axes rotates to the Cesium model axes. var offset = new UnitQuaternion(new ElementaryRotation(AxisIndicator.First, -Math.PI / 2)) * new UnitQuaternion(new ElementaryRotation(AxisIndicator.Third, Math.PI / 2)); var cesiumModelAxes = new AxesFixedOffset(m_satellite.OrientationAxes, offset); // The rotation will be from the Cesium model axes to the constrained axes. var solarPanelRotationAxes = new AxesInAxes(constrainedAxes, cesiumModelAxes); // Add a node transformation to rotate the SolarPanels node of the model. m_satellite.Extensions.GetByType <ModelGraphicsExtension>().ModelGraphics.NodeTransformations = new Dictionary <string, NodeTransformationGraphics> { { "SolarPanels", new NodeTransformationGraphics { Rotation = new AxesCesiumProperty(solarPanelRotationAxes) } } }; }