/// <summary> /// Execute the maneuver. Called automatically by Gravity Engine for maneuvers that /// have been added to the GE via AddManeuver(). /// /// Unusual to call this method directly. /// </summary> /// <param name="ge"></param> public void Execute(GravityEngine ge) { Vector3 vel = ge.GetVelocity(nbody); switch (mtype) { case Mtype.vector: vel += velChange; break; case Mtype.scalar: // scalar: adjust existing velocity by dV Vector3 change = Vector3.Normalize(vel) * dV; vel += change; break; case Mtype.circularize: // find velocity vector perpendicular to r for circular orbit // Since we could be mid-integration need to get exact position from GE double[] r_ship = new double[3]; double[] v_ship = new double[3]; ge.GetPositionVelocityScaled(nbody, ref r_ship, ref v_ship); double[] r_center = new double[3]; double[] v_center = new double[3]; ge.GetPositionVelocityScaled(centerBody, ref r_center, ref v_center); Vector3 pos_ship = new Vector3((float)r_ship[0], (float)r_ship[1], (float)r_ship[2]); Vector3 vel_ship = new Vector3((float)v_ship[0], (float)v_ship[1], (float)v_ship[2]); Vector3 pos_center = new Vector3((float)r_center[0], (float)r_center[1], (float)r_center[2]); Vector3 r = pos_ship - pos_center; // to get axis of orbit, can take v x r Vector3 axis = Vector3.Normalize(Vector3.Cross(vel_ship, pos_ship)); // vis visa for circular orbit float mu = nbody.mass * ge.massScale; float v_mag = Mathf.Sqrt(mu / Vector3.Magnitude(r)); // positive v is counter-clockwise Vector3 v_dir = Vector3.Normalize(Vector3.Cross(axis, r)); Vector3 v_circular = v_mag * v_dir; ge.SetVelocity(nbody, v_circular); break; } #pragma warning disable 162 // disable unreachable code warning if (GravityEngine.DEBUG) { Debug.Log("Applied manuever: " + LogString() + " engineRef.index=" + nbody.engineRef.index + " engineRef.bodyType=" + nbody.engineRef.bodyType + " timeError=" + (worldTime - ge.GetPhysicalTime())); Debug.Log("r= " + Vector3.Magnitude(nbody.transform.position)); } #pragma warning restore 162 // enable unreachable code warning ge.SetVelocity(nbody, vel); }
public CircularizeXfer(OrbitData fromOrbit) : base(fromOrbit) { name = "Circularize"; // find velocity vector perpendicular to r for circular orbit double[] r_ship = new double[3]; double[] v_ship = new double[3]; GravityEngine ge = GravityEngine.Instance(); ge.GetPositionVelocityScaled(fromOrbit.nbody, ref r_ship, ref v_ship); double[] r_center = new double[3]; double[] v_center = new double[3]; ge.GetPositionVelocityScaled(fromOrbit.centralMass, ref r_center, ref v_center); Vector3 pos_ship = new Vector3((float)r_ship[0], (float)r_ship[1], (float)r_ship[2]); Vector3 vel_ship = new Vector3((float)v_ship[0], (float)v_ship[1], (float)v_ship[2]); Vector3 pos_center = new Vector3((float)r_center[0], (float)r_center[1], (float)r_center[2]); Vector3 vel_center = new Vector3((float)v_center[0], (float)v_center[1], (float)v_center[2]); Vector3 r = pos_ship - pos_center; // want velocity relative to central mass (it could be moving) vel_ship = vel_ship - vel_center; // to get axis of orbit, can take r x v Vector3 axis = Vector3.Normalize(Vector3.Cross(pos_ship, vel_ship)); // vis visa for circular orbit float mu = fromOrbit.centralMass.mass * ge.massScale; float v_mag = Mathf.Sqrt(mu / Vector3.Magnitude(r)); // positive v is counter-clockwise Vector3 v_dir = Vector3.Normalize(Vector3.Cross(axis, r)); Vector3 v_circular = v_mag * v_dir; Maneuver m1; m1 = new Maneuver(); m1.nbody = fromOrbit.nbody; m1.mtype = Maneuver.Mtype.vector; m1.velChange = v_circular - vel_ship; m1.dV = Vector3.Magnitude(m1.velChange); Debug.Log(string.Format("v_ship={0} v_circular={1} axis={2}", vel_ship, v_circular, axis)); m1.worldTime = GravityEngine.Instance().GetPhysicalTime(); maneuvers.Add(m1); }