public void ResolveAtmopsherics(IMassiveBody body) { DVector2 difference = body.Position - Position; double distance = difference.Length(); difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The object is in the atmosphere of body B if (altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Simple collision detection if (altitude <= 0) { var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius); Velocity = (body.Velocity + surfaceNormal * rotationalSpeed); Rotation = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = relativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { relativeVelocity.Normalize(); // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * DragCoefficient * CrossSectionalArea); AccelerationD += dragForce / Mass; } } }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) return; DVector2 difference = body.Position - Position; double distance = difference.Length(); difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere if (altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Simple collision detection if (altitude <= 0) { var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius); Velocity = (body.Velocity + surfaceNormal * rotationalSpeed); Rotation = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = relativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { relativeVelocity.Normalize(); double dragTerm = TotalDragCoefficient() * TotalDragArea(); // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); AccelerationD += dragForce / Mass; } } }
public void ResolveAtmopsherics(IMassiveBody body) { DVector2 difference = body.Position - Position; double distance = difference.Length() - Height * 0.5; difference.Normalize(); Altitude = distance - body.SurfaceRadius; // The object is in the atmosphere of body B if (Altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = Altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Simple collision detection if (Altitude <= 0) { var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal*(body.SurfaceRadius); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; OnGround = true; } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(Altitude); RelativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = RelativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { DVector2 normalizedRelativeVelocity = RelativeVelocity.Clone(); normalizedRelativeVelocity.Normalize(); double formDragTerm = FormDragCoefficient * FrontalArea; double skinFrictionTerm = SkinFrictionCoefficient * ExposedSurfaceArea; double dragTerm = formDragTerm + skinFrictionTerm; // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = normalizedRelativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); AccelerationD = dragForce / Mass; } } }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) { return; } DVector2 difference = body.Position - Position; double heightOffset = Children.Count > 0 ? TotalHeight - Height * 0.5 : Height * 0.5; double distance = difference.Length() - heightOffset; difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere if (altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Rough metric for staying on ground from frame to frame if (altitude <= 0.0001) { _onGroundIterations = Math.Min(_onGroundIterations + 1, 10); } else { _onGroundIterations = Math.Max(_onGroundIterations - 1, 0); } // Simple collision detection if (_onGroundIterations > 5) { OnGround = true; var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius + heightOffset); Velocity = (body.Velocity + surfaceNormal * rotationalSpeed); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; AccelerationY = new DVector2(0, 0); } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = relativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { double speed = relativeVelocity.Length(); // Heating double qConv = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5)); double qRad = 3.2e-22 * Math.Pow(speed, 8) * Math.Pow(atmosphericDensity, 1.2) * Math.Sqrt((Width * 0.5)); HeatingRate = qConv + qRad; relativeVelocity.Normalize(); double formDragCoefficient = TotalFormDragCoefficient(); double skinFrictionCoefficient = TotalSkinFrictionCoefficient(); double liftCoefficient = TotalLiftCoefficient(); double formDragTerm = formDragCoefficient * TotalFormDragArea(); double skinFrictionTerm = skinFrictionCoefficient * TotalSkinFrictionArea(); double dragTerm = formDragTerm; if (!double.IsNaN(skinFrictionTerm)) { dragTerm += skinFrictionTerm; } double liftTerm = liftCoefficient * TotalLiftArea(); double turnTerm = 0; if (Settings.Default.UseTheTurnForce) { turnTerm = liftTerm * Math.Sin(Roll); liftTerm *= Math.Cos(Roll); } // Form Drag ( Fd = 0.5pv^2dA ) // Skin friction ( Fs = 0.5CfpV^2S ) DVector2 drag = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); DVector2 lift = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * liftTerm); AccelerationD = drag / Mass; DVector2 accelerationLift = lift / Mass; double alpha = GetAlpha(); double halfPi = Math.PI / 2; bool isRetrograde = alpha > halfPi || alpha < -halfPi; if (Settings.Default.UseTheTurnForce && isRetrograde) { AccelerationL.X -= accelerationLift.Y; AccelerationL.Y += accelerationLift.X; } else { AccelerationL.X += accelerationLift.Y; AccelerationL.Y -= accelerationLift.X; } } } else { HeatingRate = 0; } }
public double GetAtmosphericDensity(double altitude) { return(_proxy.GetAtmosphericDensity(altitude)); }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) { return; } DVector2 difference = body.Position - Position; double distance = difference.Length(); difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere if (altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Simple collision detection if (altitude <= 0) { var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius); Velocity = (body.Velocity + surfaceNormal * rotationalSpeed); Rotation = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocity = relativeVelocity.Length(); double velocitySquared = relativeVelocity.LengthSquared(); if (velocitySquared > 0) { double speed = relativeVelocity.Length(); // Heating HeatingRate = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5)); relativeVelocity.Normalize(); double dragTerm = TotalDragCoefficient() * TotalDragArea(); // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocitySquared * dragTerm); AccelerationD += dragForce / Mass; double reynoldsNumber = (velocity * Height) / body.GetAtmosphericViscosity(altitude); double frictionCoefficient = 0.455 / Math.Pow(Math.Log10(reynoldsNumber), 2.58); double frictionTerm = frictionCoefficient * TotalSurfaceArea(); // Skin friction ( Fs = 0.5CfpV^2S ) DVector2 skinFriction = relativeVelocity * (0.5 * atmosphericDensity * velocitySquared * frictionTerm); AccelerationD += skinFriction / Mass; } } else { HeatingRate = 0; } }
public void ResolveAtmopsherics(IMassiveBody body) { DVector2 difference = body.Position - Position; double distance = difference.Length() - Height * 0.5; difference.Normalize(); Altitude = distance - body.SurfaceRadius; // The object is in the atmosphere of body B if (Altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = Altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Simple collision detection if (Altitude <= 0) { var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; OnGround = true; } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(Altitude); RelativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = RelativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { DVector2 normalizedRelativeVelocity = RelativeVelocity.Clone(); normalizedRelativeVelocity.Normalize(); double formDragTerm = FormDragCoefficient * FrontalArea; double skinFrictionTerm = SkinFrictionCoefficient * ExposedSurfaceArea; double dragTerm = formDragTerm + skinFrictionTerm; // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = normalizedRelativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); // Reject insane forces if (dragForce.Length() < 50000000) { AccelerationD = dragForce / Mass; } } } }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) return; DVector2 difference = body.Position - Position; double heightOffset = Children.Count > 0 ? TotalHeight - Height*0.5 : Height*0.5; double distance = difference.Length() - heightOffset; difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere if (altitude < body.AtmosphereHeight) { var surfaceNormal = new DVector2(-difference.Y, difference.X); double altitudeFromCenter = altitude + body.SurfaceRadius; // Distance of circumference at this altitude ( c= 2r * pi ) double pathCirumference = 2 * Math.PI * altitudeFromCenter; double rotationalSpeed = pathCirumference / body.RotationPeriod; // Rough metric for staying on ground from frame to frame if (altitude <= 0.0001) { _onGroundIterations = Math.Min(_onGroundIterations + 1, 10); } else { _onGroundIterations = Math.Max(_onGroundIterations - 1, 0); } // Simple collision detection if (_onGroundIterations > 5) { OnGround = true; var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius + heightOffset); Velocity = (body.Velocity + surfaceNormal*rotationalSpeed); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = relativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { double speed = relativeVelocity.Length(); // Heating HeatingRate = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5)); relativeVelocity.Normalize(); double formDragCoefficient = TotalFormDragCoefficient(); double skinFrictionCoefficient = TotalSkinFrictionCoefficient(); double liftCoefficient = TotalLiftCoefficient(); double formDragTerm = formDragCoefficient * TotalFormDragArea(); double skinFrictionTerm = skinFrictionCoefficient * TotalSkinFrictionArea(); double dragTerm = formDragTerm; if (!double.IsNaN(skinFrictionTerm)) dragTerm += skinFrictionTerm; double liftTerm = liftCoefficient * TotalLiftArea() * Math.Cos(Roll); double turnTerm = liftCoefficient * TotalLiftArea() * Math.Sin(Roll); // Form Drag ( Fd = 0.5pv^2dA ) // Skin friction ( Fs = 0.5CfpV^2S ) DVector2 drag = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); DVector2 lift = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * liftTerm); DVector2 turn = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * turnTerm); AccelerationD = drag / Mass; DVector2 accelerationLift = lift / Mass; DVector2 accelerationTurn = turn / Mass; double alpha = GetAlpha(); double halfPi = Math.PI / 2; bool isRetrograde = alpha > halfPi || alpha < -halfPi; if (isRetrograde) { AccelerationL.X -= accelerationLift.Y; AccelerationL.Y += accelerationLift.X; } else { AccelerationL.X += accelerationLift.Y; AccelerationL.Y -= accelerationLift.X; } if (DateTime.Now - timestamp > TimeSpan.FromSeconds(1)) { string filename = MissionName + ".csv"; if (!File.Exists(filename)) { File.AppendAllText(filename, "Altitude, Ma, Acceleration, alpha, roll, HeatingRate, dragTerm, liftTerm, turnTerm\r\n"); } timestamp = DateTime.Now; string contents = string.Format("{0:N3}, {1:N3}, {2:N3}, {3:N3}, {4:N3}, {5:N3}, {6:N3}, {7:N3}, {8:N3}\r\n", altitude / 1000, MachNumber * 10, GetRelativeAcceleration().Length() * 10, alpha * MathHelper.RadiansToDegrees, Roll * MathHelper.RadiansToDegrees, HeatingRate / 100000, dragTerm/10, liftTerm/10, turnTerm/10); File.AppendAllText(filename, contents); } } } else { HeatingRate = 0; } }
public double GetAtmosphericDensity(double height) { return(_proxy.GetAtmosphericDensity(height)); }