Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
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)
                    }
                }
            };
        }