/// <summary> /// Initializes a new instance of the <see cref="ThrottleControlledAvionics.AtmoSim"/> class. /// </summary> /// <param name="body">Planetary body.</param> /// <param name="vsl">VesselWrapper.</param> public AtmoSim(CelestialBody body, VesselWrapper vsl) { Body = body; VSL = vsl; //0.0005 converts dynamic pressure to kPa and divides area by 2: Drag = dP * Cd * S/2. Cd = 0.0005 * Globals.Instance.ORB.DragK * PhysicsGlobals.DragCubeMultiplier * PhysicsGlobals.DragMultiplier; }
public bool ConditionsMet(VesselWrapper VSL) { var ret = Conditions.Count == 0; for(int i = 0, count = Conditions.Count; i < count; i++) ret |= Conditions[i].True(VSL); return ret; }
public static float BrakingDistance(float V0, float thrust, float mflow, float throttle, VesselWrapper VSL, out float ttb) { ttb = VSL.Engines.TTB(V0, thrust, mflow, throttle); return V0*ttb + thrust/mflow * ((ttb-VSL.Physics.M/mflow/throttle) * Mathf.Log((VSL.Physics.M-mflow*throttle*ttb)/VSL.Physics.M) - ttb); }
public RendezvousTrajectory(VesselWrapper vsl, Vector3d dV, double startUT, WayPoint target, double min_PeR, double transfer_time = -1) : base(vsl, dV, startUT, target) { MinPeR = min_PeR; TransferTime = transfer_time; TargetOrbit = Target.GetOrbit(); TargetVessel = Target.GetVessel(); update(); }
public static void AddNode(VesselWrapper VSL, Vector3d dV, double UT) { var node = VSL.vessel.patchedConicSolver.AddManeuverNode(UT); var norm = node.patch.GetOrbitNormal().normalized; var prograde = node.patch.getOrbitalVelocityAtUT(UT).normalized; var radial = Vector3d.Cross(prograde, norm).normalized; node.DeltaV = new Vector3d(Vector3d.Dot(dV, radial), Vector3d.Dot(dV, norm), Vector3d.Dot(dV, prograde)); VSL.vessel.patchedConicSolver.UpdateFlightPlan(); }
protected BaseTrajectory(VesselWrapper vsl, Vector3d dV, double startUT) { VSL = vsl; ManeuverDeltaV = dV; ManeuverDuration = VSL.Engines.TTB((float)ManeuverDeltaV.magnitude); StartUT = startUT; TimeToStart = startUT-VSL.Physics.UT; Body = VSL.vessel.orbitDriver.orbit.referenceBody; OrigOrbit = VSL.vessel.orbitDriver.orbit; Orbit = TrajectoryCalculator.NewOrbit(OrigOrbit, ManeuverDeltaV, StartUT); StartPos = Orbit.getRelativePositionAtUT(StartUT); StartVel = Orbit.getOrbitalVelocityAtUT(StartUT); }
public static float BrakingOffset(float V0, VesselWrapper VSL) { float ttb; return BrakingDistance(V0, VSL, out ttb)/V0; }
protected override bool Evaluate(VesselWrapper VSL) { return VSL.LandedOrSplashed; }
protected override float VesselValue(VesselWrapper VSL) { return VSL.HorizontalSpeed; }
protected override float VesselValue(VesselWrapper VSL) { return VSL.VerticalSpeed.Absolute; }
protected override float VesselValue(VesselWrapper VSL) { return (float)VSL.vessel.staticPressurekPa; }
protected void Log(VesselWrapper VSL, string msg, params object[] args) { VSL.vessel.Log(msg, args); }
public static VesselConfig GetConfig(VesselWrapper VSL) { return GetConfig(VSL.vessel); }
public static bool AvoideVessel(VesselWrapper vsl, Vector3d dir, float dist, Vector3d dV, float r2, Bounds exhaust2, Transform refT2, out Vector3d maneuver, float threshold = -1) { maneuver = Vector3d.zero; //filter vessels on non-collision courses var dVn = dV.normalized; var cosA = Mathf.Clamp(Vector3.Dot(dir, dVn), -1, 1); var collision_dist = threshold.Equals(0)? 2*dist-vsl.Geometry.DistToBounds(vsl.Physics.wCoM+dir*dist)- Mathf.Sqrt(exhaust2.SqrDistance(refT2.InverseTransformPoint(vsl.Physics.wCoM))) : Mathf.Max(vsl.Geometry.R, dist-vsl.Geometry.DistToBounds(vsl.Physics.wCoM+dir*dist)) + Mathf.Max(r2, dist-Mathf.Sqrt(exhaust2.SqrDistance(refT2.InverseTransformPoint(vsl.Physics.wCoM)))); // vsl.Log("R {}, R2 {}; r {}, r2 {}", vsl.Geometry.R, r2, // dist-vsl.DistToBounds(vsl.wCoM+dir*dist), // dist-Mathf.Sqrt(exhaust2.SqrDistance(refT2.InverseTransformPoint(vsl.wCoM))));//debug // Utils.Log("{}: cosA: {}, threshold {}", vsl.vessel.vesselName, cosA, threshold);//debug if(cosA <= 0) goto check_distance; if(threshold < 0) threshold = CPS.MinDistance; var sinA = Mathf.Sqrt(1-cosA*cosA); var min_separation = dist*sinA; var sep_threshold = collision_dist+threshold; // Utils.Log("{}: min_sep > sep_thresh: {} > {}, threshold {}", // vsl.vessel.vesselName, min_separation, sep_threshold, threshold);//debug if(min_separation > sep_threshold) goto check_distance; //calculate time to collision var vDist = 0f; var alpha = Mathf.Acos(cosA); var dVm = dV.magnitude; if(sinA <= 0) vDist = dist-sep_threshold; else if(dist > sep_threshold) vDist = sep_threshold*Mathf.Sin(Mathf.Asin(min_separation/sep_threshold)-alpha)/sinA; var vTime = Utils.ClampL(vDist, 0.1f)/dVm; // Utils.Log("{}: vTime > SafeTime: {} > {}", // vsl.vessel.vesselName, vTime, CPS.SafeTime/Utils.Clamp(Mathf.Abs(Vector3.Dot(vsl.wMaxAngularA, dVn)), 0.01f, 1f));//debug if(vTime > SafeTime(vsl, dVn)) goto check_distance; //calculate maneuver Vector3d side; if(cosA < 0.9) side = (dVn*cosA-dir).normalized; else if(Math.Abs(Vector3d.Dot(dVn, vsl.Physics.Up)) < 0.9) side = Vector3d.Cross(dVn, vsl.Physics.Up).normalized; else side = Vector3d.Cross(dVn, vsl.OnPlanetParams.Fwd).normalized; // if(dist > sep_threshold) // { // var beta = Mathf.Asin(sep_threshold/dist)-alpha; // maneuver = (Mathf.Sin(beta)*side + dVn*(Mathf.Cos(beta)-1)).normalized; // } // else maneuver = side; maneuver += vsl.Physics.Up*Mathf.Sign(Vector3.Dot(dir, vsl.Physics.Up))*(min_separation/sep_threshold-1); maneuver *= (sep_threshold-min_separation) / Math.Sqrt(vTime); // maneuver = (-vsl.Up*Mathf.Sign(Vector3.Dot(dir, vsl.Up))*(1-min_separation/sep_threshold) + // (dVn*cosA-dir).normalized).normalized * (sep_threshold-min_separation) / vTime; // vsl.Log("\ndist {}\ndV {}\nmaneuver: {}\n" + // "vTime {}, vDist {}, min sep {}, sep_thresh {}", // dir*dist, dV, maneuver, vTime, vDist, min_separation, sep_threshold);//debug #if DEBUG Collided |= dist < collision_dist; #endif //if distance is not safe, correct course anyway check_distance: var collision = !maneuver.IsZero(); dist -= collision_dist; if(dist < threshold) { var dist_to_safe = Utils.ClampH(dist-threshold, -0.01f); var dc = dir*dist_to_safe; if(vsl.HorizontalSpeed.NeededVector.sqrMagnitude > CPS.LatAvoidMinVelSqr) { var lat_avoid = Vector3d.Cross(vsl.Physics.Up, vsl.HorizontalSpeed.NeededVector.normalized); dc = Vector3d.Dot(dc, lat_avoid) >= 0? lat_avoid*dist_to_safe : lat_avoid*-dist_to_safe; } if(dc.sqrMagnitude > 0.25) maneuver += dc/CPS.SafeTime*2; // vsl.Log("adding safe distance correction: {}", dc/CPS.SafeTime*2);//debug } // #if DEBUG // Dir = dir*dist; // DeltaV = dV; // Maneuver = maneuver; // #endif return collision; }
public static bool AvoidStatic(VesselWrapper vsl, Vector3d dir, float dist, Vector3d dV, out Vector3d maneuver) { maneuver = Vector3d.zero; var dVn = dV.normalized; var cosA = Mathf.Clamp(Vector3.Dot(dir, dVn), -1, 1); if(cosA <= 0) return false; var sinA = Mathf.Sqrt(1-cosA*cosA); var vdist = dist*cosA; var min_separation = dist*sinA; if(min_separation > vsl.Geometry.D || min_separation > vsl.Geometry.R && vdist < min_separation) return false; maneuver = (dVn*cosA-dir).normalized; var vTime = dist*cosA/dV.magnitude; if(vTime > SafeTime(vsl, dVn)) return false; maneuver *= (vsl.Geometry.D-min_separation) / Math.Sqrt(vTime); return true; }
public static float BrakingNodeCorrection(float V0, VesselWrapper VSL) { float ttb; var offset = BrakingOffset(V0, VSL, out ttb); return offset - ttb/2; }
public static float BrakingDistance(float V0, VesselWrapper VSL, out float ttb) { return BrakingDistance(V0, VSL.Engines.MaxThrustM, VSL.Engines.MaxMassFlow, ThrottleControl.NextThrottle((float)V0, 1, VSL), VSL, out ttb); }
public static Sweep Cast(VesselWrapper vsl, Vector3 dir, float angle, float dist) { var s = new Sweep(vsl); s.Cast(dir, angle, dist); return s; }
public void Copy(Sweep s) { VSL = s.VSL; L = s.L; C = s.C; R = s.R; Obstacle = s.Obstacle; Altitude = s.Altitude; Maneuver = s.Maneuver; Valid = s.Valid; }
protected override bool Evaluate(VesselWrapper VSL) { return(VSL.OnPlanet); }
public HorizontalSpeedProps(VesselWrapper vsl) : base(vsl) { }
static float SafeTime(VesselWrapper vsl, Vector3d dVn) { return CPS.SafeTime/Utils.Clamp(Mathf.Abs(Vector3.Dot(vsl.Torque.MaxCurrent.AA, vsl.LocalDir(dVn))), 0.01f, 1f); }
public AltitudeProps(VesselWrapper vsl) : base(vsl) { }
public static float NextThrottle(float dV, float throttle, VesselWrapper VSL) { return NextThrottle(dV, throttle, VSL.Physics.M, VSL.Engines.MaxThrustM, VSL.Engines.ThrustDecelerationTime); }
public OnPlanetProps(VesselWrapper vsl) : base(vsl) { }
/// <summary> /// Perform the Action on a specified VSL. /// Returns true if it is not finished and should be called on next update. /// False if it is finished. /// </summary> /// <param name="VSL">VesselWrapper</param> protected virtual bool Action(VesselWrapper VSL) { return false; }
protected override bool Evaluate(VesselWrapper VSL) { return(VSL.OnPlanet && VSL.Body.atmosphere); }
public bool Execute(VesselWrapper VSL) { if(Done) return false; if(!Active) { Active = true; if(Parent != null) Parent.OnChildActivate(this); } Done = !Action(VSL); Active &= !Done; return !Done; }
protected override bool Evaluate(VesselWrapper VSL) { return(VSL.LandedOrSplashed); }
protected override float VesselValue(VesselWrapper VSL) { return (float)VSL.vessel.srfSpeed; }
protected override float VesselValue(VesselWrapper VSL) { return(VSL.Altitude); }
protected override float VesselValue(VesselWrapper VSL) { return VSL.Altitude; }
protected override float VesselValue(VesselWrapper VSL) { return((float)VSL.vessel.dynamicPressurekPa); }
protected override bool Evaluate(VesselWrapper VSL) { return VSL.OnPlanet && VSL.Body.atmosphere; }
protected override float VesselValue(VesselWrapper VSL) { return((float)VSL.vessel.srfSpeed); }
protected override bool Evaluate(VesselWrapper VSL) { return VSL.OnPlanet; }
protected override float VesselValue(VesselWrapper VSL) { return(VSL.HorizontalSpeed); }
public InfoProps(VesselWrapper vsl) : base(vsl) { }
protected override float VesselValue(VesselWrapper VSL) { return(VSL.VerticalSpeed.Absolute); }