【基于STK Components(STK组件)的.Net4.5编程】之[SatelliteVisibility.sln]卫星可见性计算
项目代码及swf录制视频下载地址:
【带运行效果录屏】卫星可见性计算(基于STKComponents组件编程).zip-其它文档类资源-CSDN下载
Code is everything!直接上代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//Add using directives for STK Components namespaces:
using AGI.Foundation;
using AGI.Foundation.Access;
using AGI.Foundation.Access.Constraints;
using AGI.Foundation.Celestial;
using AGI.Foundation.Coordinates;
using AGI.Foundation.Geometry;
using AGI.Foundation.Graphics;
using AGI.Foundation.Graphics.Advanced;
using AGI.Foundation.Platforms;
using AGI.Foundation.Propagators;
using AGI.Foundation.Time;
namespace SatelliteVisibility
{
public partial class Form1 : Form
{
// for user input values.
public double longitude;
public double latitude;
public double minimumElevationAngle;
public TwoLineElementSet tle;
public JulianDate startDate;
public JulianDate endDate;
// for animation.
public ModelPrimitive satellite;
public MarkerBatchPrimitive facility;
public PolylinePrimitive orbitLine;
public PolylinePrimitive accessLine;
public List<Cartesian> orbitPoints;
// for access computation and animation update.
public Platform satellitePlatform;
public Platform facilityPlatform;
public PointEvaluator satellitePositionEvaluator;
public AxesEvaluator satelliteOrientationEvaluator;
public PointEvaluator facilityInertialEvaluator;
public TimeIntervalCollection accessIntervals;
public Insight3D Insight3D;
public struct ViewingOpportunity
{
public GregorianDate StartDate;
public GregorianDate EndDate;
public double ApproachAzimuth;
public double DepartureAzimuth;
}
public Form1()
{
InitializeComponent();
//JSLS添加
Insight3D = new Insight3D();
Insight3D.Location = new System.Drawing.Point(8, 8);
Insight3D.Name = "Insight3D";
Insight3D.Size = new Size(752, 752); //三维地球视图的尺寸大小,需要调试运行时调整
tabPage_Visualization.Controls.Add(Insight3D);
}
private void Form1_Load(object sender, EventArgs e)
{
//获取地球中心体——我们需要它来计算接近和离开的方位角,卫星在地球参考系中的位置,以及卫星的方向轴。
EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;
// 从[hs601.mdl]创建 卫星对象
satellite = new ModelPrimitive("hs601.mdl");
satellite.ReferenceFrame = earth.InertialFrame;
orbitLine = new PolylinePrimitive(PolylineType.LineStrip, SetHint.Frequent);
orbitLine.ReferenceFrame = earth.InertialFrame;
accessLine = new PolylinePrimitive(PolylineType.Lines, SetHint.Frequent);
accessLine.ReferenceFrame = earth.InertialFrame;
// 用[facility.png]创建标记以表示场景中的设施
facility = new MarkerBatchPrimitive(SetHint.Infrequent);
facility.RenderPass = MarkerBatchRenderPass.Translucent;
facility.Texture = SceneManager.Textures.FromUri("facility.png");
// Create the list of points for the orbit polyline.
orbitPoints = new List<Cartesian>();
// Add TimeChanged event handler to the SceneManager
SceneManager.TimeChanged += TimeChanged;
}
private void maskedTextBox_StartDate_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
MessageBox.Show("输入的时间格式不正确,请重新输入!");
}
private void maskedTextBox_StopDate_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
MessageBox.Show("输入的时间格式不正确,请重新输入!");
}
public void TimeChanged(object sender, TimeChangedEventArgs message)
{
// Should not execute if the scene is not animating so the event does not interfere
// with the AccessQuery.
if (satellitePositionEvaluator != null && satelliteOrientationEvaluator != null)
{
// Set the current position and orientation of the satellite at the current time.
satellite.Position = satellitePositionEvaluator.Evaluate(message.Time);
satellite.Orientation = satelliteOrientationEvaluator.Evaluate(message.Time);
// Add the point to the list of polyline points.
orbitPoints.Add(satellite.Position);
orbitLine.Set(orbitPoints);
// If the satellite has access to the facility at the current time, render
// a polyline from the satellite to the facility.
if (accessIntervals.Contains(message.Time))
{
List<Cartesian> accessPoints = new List<Cartesian>
{
satellite.Position,
facilityInertialEvaluator.Evaluate(message.Time)
};
accessLine.Set(accessPoints, new[] { Color.Yellow, Color.Yellow }, RenderPassHint.Opaque);
if (!SceneManager.Primitives.Contains(accessLine))
{
SceneManager.Primitives.Add(accessLine);
}
}
else
{
// Otherwise, remove any polyline from the satellite to the facility if it exists.
if (SceneManager.Primitives.Contains(accessLine))
{
SceneManager.Primitives.Remove(accessLine);
}
}
}
}
public void ResetScene()
{
// If a satellite has been added to the SceneManager,
// then all three primitives were added.
if (SceneManager.Primitives.Contains(satellite))
{
SceneManager.Primitives.Remove(satellite);
SceneManager.Primitives.Remove(facility);
SceneManager.Primitives.Remove(orbitLine);
}
// The polyline from the satellite to the facility is not always included
// in the Scene, so must have its own check.
if (SceneManager.Primitives.Contains(accessLine))
{
SceneManager.Primitives.Remove(accessLine);
}
// Remove the current line representing the orbit.
orbitPoints.Clear();
}
public void UpdateVisualization()
{
// Reset the Scene in case the button was pressed more than once.
ResetScene();
EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;
// Get the starting position and orientation of the satellite and set the global evaluators
// for the TimeChanged event handler.
satellitePositionEvaluator = GeometryTransformer.ObservePoint(satellitePlatform.LocationPoint, earth.InertialFrame);
satelliteOrientationEvaluator = GeometryTransformer.GetAxesTransformation(satellitePlatform.OrientationAxes, earth.InertialFrame.Axes);
facilityInertialEvaluator = GeometryTransformer.ObservePoint(facilityPlatform.LocationPoint, earth.InertialFrame);
Cartesian satellitePosition = satellitePositionEvaluator.Evaluate(startDate);
UnitQuaternion satelliteOrientation = satelliteOrientationEvaluator.Evaluate(startDate);
satellite.Position = satellitePosition;
satellite.Orientation = satelliteOrientation;
// Set the scale once, then add it to the Scene.
satellite.Scale = 1e5;
SceneManager.Primitives.Add(satellite);
// Set the position once, then add it to the Scene.
Cartographic facilityPosition = new Cartographic(Trig.DegreesToRadians(longitude), Trig.DegreesToRadians(latitude), 0.0);
facility.SetCartographic(earth, new[] { facilityPosition });
SceneManager.Primitives.Add(facility);
// Add the satellites initial position to the set of orbit points.
orbitPoints.Add(satellitePosition);
SceneManager.Primitives.Add(orbitLine);
// Set up animation times.
SimulationAnimation animation = (SimulationAnimation)SceneManager.Animation;
if (animation.IsAnimating)
animation.Reset();
animation.TimeStep = new Duration(0, 5.0);
animation.StartCycle = SimulationAnimationCycle.Continue;
animation.EndCycle = SimulationAnimationCycle.Loop;
animation.StartTime = startDate;
animation.EndTime = endDate;
animation.Time = startDate;
// Start animation.
animation.PlayForward();
}
public AccessQuery CreateAccessQuery()
{
// Create an Access constraint requiring that the satellite be above a particular elevation
// angle relative to the local horizontal plane of the facility.
ElevationAngleConstraint elevationAngleConstraint = new ElevationAngleConstraint();
elevationAngleConstraint.MinimumValue = Trig.DegreesToRadians(minimumElevationAngle);
elevationAngleConstraint.MaximumValue = Constants.HalfPi;
//Create a new link between the satellite and facility, and assign that link to the
//elevation angle constraint. Then specify that the elevation angle constraint applies
//to the receiving end of the link (the facility).
LinkInstantaneous link = new LinkInstantaneous(satellitePlatform, facilityPlatform);
elevationAngleConstraint.ConstrainedLink = link;
elevationAngleConstraint.ConstrainedLinkEnd = LinkRole.Receiver;
return elevationAngleConstraint;
}
public List<ViewingOpportunity> GetViewingOpportunities()
{
EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;
// Use the CreateAccessQuery method below to create an AccessQuery object.
AccessQuery access = CreateAccessQuery();
//Create the access evaluator. An access evaluator generally needs a specified
//observer. This is because access computations with light time delays can cause
//different platforms to have different time intervals for the same constraints.
//However, AccessQueries that are purely made out of instantaneous links (like here)
//do not need a specified observer.
AccessEvaluator evaluator = access.GetEvaluator();
// Compute the time intervals when the viewing location is able to see the satellite.
AccessQueryResult accessResult = evaluator.Evaluate(startDate, endDate);
accessIntervals = accessResult.SatisfactionIntervals;
// Get an evaluator to find the topographic azimuth, elevation, and range of the satellite
// as observed by the viewing location. We'll use this evaluator to evaluate the AER at the
// start and end of each viewing opportunity interval.
VectorTrueDisplacement vector = new VectorTrueDisplacement(facilityPlatform.LocationPoint, satellitePlatform.LocationPoint);
MotionEvaluator<AzimuthElevationRange> aerEvaluator = earth.GetAzimuthElevationRangeEvaluator(vector);
List<ViewingOpportunity> results = new List<ViewingOpportunity>();
// Copy the output intervals to the return structure.
foreach (TimeInterval interval in accessIntervals)
{
ViewingOpportunity opportunity = new ViewingOpportunity();
// Convert the start and stop dates of the interval to UTC GregorianDate instances for
// human-readable display.
opportunity.StartDate = interval.Start.ToGregorianDate();
opportunity.EndDate = interval.Stop.ToGregorianDate();
// Compute the azimuth of the satellite observed from the viewing location
// at the start of the interval.
AzimuthElevationRange aer = aerEvaluator.Evaluate(interval.Start);
opportunity.ApproachAzimuth = Trig.RadiansToDegrees(aer.Azimuth);
// Compute the azimuth of the satellite observed from the viewing location
// at the end of the interval.
aer = aerEvaluator.Evaluate(interval.Stop);
opportunity.DepartureAzimuth = Trig.RadiansToDegrees(aer.Azimuth);
results.Add(opportunity);
}
// Return the ViewingOpportunity instances
return results;
}
private void button_Go_Click(object sender, EventArgs e)
{
try
{
//Parse the text input from the boxes on the form into appropriate
//class instances and store them in private variables.
startDate = GregorianDate.Parse(maskedTextBox_StartDate.Text).ToJulianDate();
endDate = GregorianDate.Parse(maskedTextBox_StopDate.Text).ToJulianDate();
latitude = double.Parse(textBox_WeiDu.Text);
longitude = double.Parse(textBox_JingDu.Text);
minimumElevationAngle = double.Parse(textBox_ZheBiJiao.Text);
tle = new TwoLineElementSet(textBox_TLE.Text);
EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;
// Create an SGP4 propagator to propagate the TLE.
Sgp4Propagator propagator = new Sgp4Propagator(tle);
// Create a Platform for the satellite, including a Point representing the position
// as reported by the propagator. The propagator produces raw ephemeris, while the
// Point enables the results of propagation to work with the GeometryTransformer in
// order to observe the ephemeris in different reference frames.
satellitePlatform = new Platform();
PropagatorPoint point = propagator.CreatePoint();
satellitePlatform.LocationPoint = point;
satellitePlatform.OrientationAxes = new AxesVehicleVelocityLocalHorizontal(earth.InertialFrame, satellitePlatform.LocationPoint);
// Create a facility at the view location. The longitude and latitude of the facility's
// location are specified using radians, so convert degrees to radians.
// Since we don't care about the orientation of the facility, we just
// use Axes.Root.
facilityPlatform = new Platform();
Cartographic location = new Cartographic(Trig.DegreesToRadians(longitude), Trig.DegreesToRadians(latitude), 0.0);
facilityPlatform.LocationPoint = new PointCartographic(CentralBodiesFacet.GetFromContext().Earth, location);
facilityPlatform.OrientationAxes = Axes.Root;
// Call method GetViewingOpportunities to calculate the viewing opportunities from
// the input parameters.
List<ViewingOpportunity> opportunities = GetViewingOpportunities();
// Clear all items from the Output box before writing anything new.
listView_DataOutput.Items.Clear();
// Write each viewing opportunity to the output box on the form.
foreach (ViewingOpportunity opportunity in opportunities)
{
ListViewItem item = new ListViewItem(new[]
{
opportunity.StartDate.ToString(),
opportunity.ApproachAzimuth.ToString(),
opportunity.EndDate.ToString(),
opportunity.DepartureAzimuth.ToString(),
});
listView_DataOutput.Items.Add(item);
}
// Update the animation in the Insight3D component.
UpdateVisualization();
}
catch
{
// If any of the input values could not be parsed...
MessageBox.Show("Check your input values!");
}
}
}
}
运行效果:
更多推荐
【基于STK Components(STK组件)的.Net4.5编程】之[SatelliteVisibility.sln]卫星可见性计算
发布评论