void DisplayPhaseChangeMode() { ImGui.SliderAngle("PhaseAngle", ref _phaseAngleRadians); var manuvers = InterceptCalcs.OrbitPhasingManuvers(_currentKE, _sgp, _atDatetime, _phaseAngleRadians); double totalManuverDV = 0; foreach (var manuver in manuvers) { ImGui.Text(manuver.deltaV.Length() + "Δv"); totalManuverDV += manuver.deltaV.Length(); ImGui.Text("Seconds: " + manuver.timeInSeconds); } ImGui.Text("Total Δv"); ImGui.SameLine(); ImGui.Text("for all manuvers: " + Stringify.Velocity(totalManuverDV)); if (ImGui.Button("Make it so")) { NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, _atDatetime, manuvers[0].deltaV); DateTime futureDate = _atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds); NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, futureDate, manuvers[1].deltaV); } }
void InsertionCalcs() { OrbitDB targetOrbit = TargetEntity.Entity.GetDataBlob <OrbitDB>(); (ECSLib.Vector3 position, DateTime eti)targetIntercept = InterceptCalcs.GetInterceptPosition(OrderingEntity.Entity, TargetEntity.Entity.GetDataBlob <OrbitDB>(), _departureDateTime); DateTime estArivalDateTime = targetIntercept.eti; //rough calc. /* * double x = (_radialDV * Math.Cos(_departureAngle)) - (_progradeDV * Math.Sin(_departureAngle)); * double y = (_radialDV * Math.Sin(_departureAngle)) + (_progradeDV * Math.Cos(_departureAngle)); */ var norm = Vectors.Vector2.Normalise(_departureOrbitalVelocity); double x = norm.X * _radialDV; double y = norm.Y * _progradeDV; _deltaV_MS = new ECSLib.Vector3(x, y, 0); var insertionVector2d = OrbitProcessor.GetOrbitalInsertionVector(_departureOrbitalVelocity, targetOrbit, estArivalDateTime);//_departureOrbitalVelocity - parentOrbitalVector; _insertionOrbitalVelocity = new ECSLib.Vector3(insertionVector2d.X, insertionVector2d.Y, 0); _insertionOrbitalVelocity += Distance.MToAU(_deltaV_MS); _insertionOrbitalSpeed = _insertionOrbitalVelocity.Length(); _insertionAngle = Math.Atan2(_insertionOrbitalVelocity.Y, _insertionOrbitalVelocity.X); _moveWidget.SetArivalProgradeAngle(_insertionAngle); /* * var sgpCBAU = GameConstants.Science.GravitationalConstant * (_massCurrentBody + _massOrderingEntity) / 3.347928976e33;// (149597870700 * 149597870700 * 149597870700); * var ralPosCBAU = OrderingEntity.Entity.GetDataBlob<PositionDB>().RelativePosition_AU; * var smaCurrOrbtAU = OrderingEntity.Entity.GetDataBlob<OrbitDB>().SemiMajorAxis; * var velAU = OrbitProcessor.PreciseOrbitalVector(sgpCBAU, ralPosCBAU, smaCurrOrbtAU); */ }
void DisplayHohmannMode() { double mySMA = _currentKE.SemiMajorAxis; float smaMin = 1; float smaMax = (float)OrbitProcessor.GetSOI_m(Entity.GetSOIParentEntity(_orderEntity)); if (ImGui.Combo("Target Object", ref _selectedSibling, _siblingNames, _siblingNames.Length)) { Entity selectedSib = _siblingEntities[_selectedSibling]; if (selectedSib.HasDataBlob <OrbitDB>()) { _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <OrbitDB>().SemiMajorAxis; } if (selectedSib.HasDataBlob <OrbitUpdateOftenDB>()) { _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <OrbitUpdateOftenDB>().SemiMajorAxis; } if (selectedSib.HasDataBlob <NewtonMoveDB>()) { _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <NewtonMoveDB>().GetElements().SemiMajorAxis; } } //TODO this should be radius from orbiting body not major axies. ImGui.SliderFloat("Target SemiMajorAxis", ref _targetSMA, smaMin, smaMax); var manuvers = InterceptCalcs.Hohmann2(_sgp, mySMA, _targetSMA); double totalManuverDV = 0; foreach (var manuver in manuvers) { ImGui.Text(manuver.deltaV.Length() + "Δv"); totalManuverDV += manuver.deltaV.Length(); } if (totalManuverDV > _totalDV) { ImGui.TextColored(new Vector4(0.9f, 0, 0, 1), "Total Δv for all manuvers: " + Stringify.Velocity(totalManuverDV)); } else { ImGui.Text("Total Δv for all manuvers: " + Stringify.Velocity(totalManuverDV)); } if (ImGui.Button("Make it so")) { NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, _atDatetime, manuvers[0].deltaV); DateTime futureDate = _atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds); NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, futureDate, manuvers[1].deltaV); } }
public void TestIntercept() { double myMass = 10000; double parentMass = 1.989e30; //solar mass. Game game = new Game(); EntityManager mgr = new EntityManager(game, false); BaseDataBlob[] parentblobs = new BaseDataBlob[3]; parentblobs[0] = new PositionDB(mgr.ManagerGuid) { X = 0, Y = 0, Z = 0 }; parentblobs[1] = new MassVolumeDB() { Mass = parentMass }; parentblobs[2] = new OrbitDB(); Entity parentEntity = new Entity(mgr, parentblobs); Vector3 currentPos = new Vector3 { X = -0.77473184638034, Y = 0.967145228951685 }; Vector3 currentVelocity = new Vector3 { Y = Distance.KmToAU(40) }; double nonNewtSpeed = Distance.KmToAU(283.018); Vector3 targetObjPosition = new Vector3 { X = 0.149246434443459, Y = -0.712107888348067 }; Vector3 targetObjVelocity = new Vector3 { Y = Distance.KmToAU(35) }; double sgp = GameConstants.Science.GravitationalConstant * (parentMass + myMass) / 3.347928976e33; //KeplerElements ke = OrbitMath.KeplerFromVelocityAndPosition(sgp, targetObjPosition, targetObjVelocity); var currentDateTime = new DateTime(2000, 1, 1); OrbitDB targetOrbit = OrbitDB.FromVector(parentEntity, myMass, parentMass, sgp, targetObjPosition, targetObjVelocity, currentDateTime); var intercept = InterceptCalcs.GetInterceptPosition2(currentPos, nonNewtSpeed, targetOrbit, currentDateTime); var futurePos1 = Distance.AuToKm(OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, intercept.Item2)); var futurePos2 = Distance.AuToKm(intercept.Item1); Assert.AreEqual(futurePos1.Length(), futurePos2.Length(), 0.01); Assert.AreEqual(futurePos1.X, futurePos2.X, 0.01); Assert.AreEqual(futurePos1.Y, futurePos2.Y, 0.01); Assert.AreEqual(futurePos1.Z, futurePos2.Z, 0.01); var time = intercept.Item2 - currentDateTime; var distance = (currentPos - intercept.Item1).Length(); var distancekm = Distance.AuToKm(distance); var speed = distance / time.TotalSeconds; var speed2 = distancekm / time.TotalSeconds; var distb = nonNewtSpeed * time.TotalSeconds; var distbKM = Distance.AuToKm(distb); var timeb = distance / nonNewtSpeed; Assert.AreEqual(nonNewtSpeed, speed, 1.0e-10); var dif = distancekm - distbKM; Assert.AreEqual(distancekm, distbKM, 0.25); }
public static void LaunchMissile(Entity launchingEntity, Entity targetEntity, double launchForce, OrdnanceDesign missileDesign, int count) { var atDatetime = launchingEntity.Manager.StarSysDateTime; var parentPositionDB = launchingEntity.GetDataBlob <PositionDB>(); Vector3 parentPosition = parentPositionDB.AbsolutePosition_m; var parentPosRal = parentPositionDB.RelativePosition_m; var tgtEntityOrbit = targetEntity.GetDataBlob <OrbitDB>(); if (targetEntity.HasDataBlob <OrbitUpdateOftenDB>()) { tgtEntityOrbit = targetEntity.GetDataBlob <OrbitUpdateOftenDB>(); } //MissileLauncherAtb launcherAtb; VolumeStorageDB cargo = launchingEntity.GetDataBlob <VolumeStorageDB>(); int numMis = cargo.TypeStores[missileDesign.CargoTypeID].CurrentStoreInUnits[missileDesign.ID]; if (numMis < 1) { return; } double launchSpeed = launchForce / missileDesign.MassPerUnit; double burnTime = ((missileDesign.WetMass - missileDesign.DryMass) / missileDesign.BurnRate) * 0.8; //use 80% of fuel. double drymass = (missileDesign.WetMass - missileDesign.DryMass) * 0.8; //use 80% of fuel. double launchManuverDv = OrbitMath.TsiolkovskyRocketEquation(missileDesign.WetMass, drymass, missileDesign.ExaustVelocity); double totalDV = OrbitMath.TsiolkovskyRocketEquation(missileDesign.WetMass, missileDesign.DryMass, missileDesign.ExaustVelocity); double speed = launchSpeed + launchManuverDv; var misslPositionDB = (PositionDB)parentPositionDB.Clone(); Vector3 parentVelocity = Entity.GetRalitiveFutureVelocity(launchingEntity, launchingEntity.StarSysDateTime); var orderabledb = new OrderableDB(); var newtmovedb = new NewtonMoveDB(misslPositionDB.Parent, parentVelocity); string defaultName = "Missile"; string factionsName = missileDesign.Name; if (count > 1) { defaultName += " x" + count; factionsName += " x" + count; } List <BaseDataBlob> dataBlobs = new List <BaseDataBlob>(); dataBlobs.Add(new ProjectileInfoDB(launchingEntity.Guid, count)); dataBlobs.Add(new ComponentInstancesDB()); dataBlobs.Add(misslPositionDB); dataBlobs.Add(MassVolumeDB.NewFromMassAndVolume(missileDesign.WetMass, missileDesign.WetMass)); dataBlobs.Add(new NameDB(defaultName, launchingEntity.FactionOwner, factionsName)); dataBlobs.Add(newtmovedb); dataBlobs.Add(orderabledb); var newMissile = Entity.Create(launchingEntity.Manager, launchingEntity.FactionOwner, dataBlobs); foreach (var tuple in missileDesign.Components) { EntityManipulation.AddComponentToEntity(newMissile, tuple.design, tuple.count); } var newtdb = newMissile.GetDataBlob <NewtonThrustAbilityDB>(); newtdb.DryMass_kg = missileDesign.MassPerUnit; newtdb.SetFuel(missileDesign.WetMass - missileDesign.MassPerUnit); bool directAttack = false; if (directAttack) { /* * var tgtintercept = OrbitMath.GetInterceptPosition_m(parentPosition, speed, tgtEntityOrbit, atDatetime); * var tgtEstPos = tgtintercept.position + targetEntity.GetDataBlob<PositionDB>().RelativePosition_m; * * var tgtCurPos = Entity.GetPosition_m(targetEntity, atDatetime); * * var vectorToTgt = Vector3.Normalise(tgtCurPos - parentPosRal); * * //var vectorToTgt = Vector3.Normalise(tgtEstPos - parentPosRal); * var launcherVector = vectorToTgt * launchSpeed; * * * var launchVelocity = parentVelocity + launcherVector; * var manuverDV = vectorToTgt * launchManuverDv; * * launchVelocity = parentVelocity + launcherVector; */ ThrustToTargetCmd.CreateCommand(launchingEntity.FactionOwner, newMissile, launchingEntity.StarSysDateTime, targetEntity); } else { var launchOrbit = launchingEntity.GetDataBlob <OrbitDB>(); if (launchingEntity.HasDataBlob <OrbitUpdateOftenDB>()) { launchOrbit = launchingEntity.GetDataBlob <OrbitUpdateOftenDB>(); } var launchTrueAnomaly = OrbitProcessor.GetTrueAnomaly(launchOrbit, atDatetime); var targetTrueAnomaly = OrbitProcessor.GetTrueAnomaly(tgtEntityOrbit, atDatetime); var phaseAngle = targetTrueAnomaly - launchTrueAnomaly; var manuvers = InterceptCalcs.OrbitPhasingManuvers(launchOrbit, atDatetime, phaseAngle); var manuverDV = manuvers[0].deltaV; //newtmovedb.ActionOnDateTime = atDatetime; //newtmovedb.DeltaVForManuver_FoRO_m = manuverDV; NewtonThrustCommand.CreateCommand(launchingEntity.FactionOwner, newMissile, atDatetime, manuverDV); DateTime futureDate = atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds); Vector3 futureDV = manuvers[1].deltaV; NewtonThrustCommand.CreateCommand(launchingEntity.FactionOwner, newMissile, futureDate, futureDV); //ThrustToTargetCmd.CreateCommand(launchingEntity.FactionOwner, newMissile, futureDate + TimeSpan.FromSeconds(1), targetEntity); } cargo.RemoveCargoByUnit(missileDesign, 1); //remove missile from parent. }