/// <summary>
        /// Load TLEs from a satellite database and create marker primitives for each satellite
        /// </summary>
        private void CreateSatellites(string fileName)
        {
            m_satellites.Clear();

            JulianDate?epoch = null;

            StkSatelliteDatabase db = new StkSatelliteDatabase(GetDataFilePath("SatelliteDatabase"), fileName);

            foreach (StkSatelliteDatabaseEntry entry in db.GetEntries())
            {
                if (entry.TwoLineElementSet != null)
                {
                    Sgp4Propagator propagator = new Sgp4Propagator(entry.TwoLineElementSet);

                    if (epoch == null)
                    {
                        epoch = propagator.InitialConditions.Epoch;
                    }

                    Duration epochDifference = epoch.Value - propagator.InitialConditions.Epoch;
                    if (epochDifference < Duration.FromDays(1))
                    {
                        m_satellites.Add(propagator.GetEvaluator(), entry.TwoLineElementSet.Epoch);
                    }
                }
            }

            SetText(m_satellites.Count);

            JulianDate time = epoch.Value.ToTimeStandard(TimeStandard.InternationalAtomicTime);

            // Set epoch time
            m_animation.Pause();
            m_animation.StartTime = time;
            m_animation.EndTime   = time.AddDays(1.0);
            m_animation.Time      = time;
            m_animation.PlayForward();
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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)
                    }
                }
            };
        }