Beispiel #1
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        public static bool get_launch_params(CelestialBody depBody,
                                             ref DepManuever manuever)
        {
            BodyData depData = new BodyData();
            depBody.get_data(ref depData);
            double mu = depData.gravParameter;
            double R = depData.radius;
            double r0 = R + manuever.h;

            double vk = Math.Sqrt(mu / r0);

            double i = manuever.orbit.i * math.RAD;
            double Omega = manuever.orbit.Omega * math.RAD;

            if (i < Math.Abs(manuever.launchLat))
                return false;

            double sin_A = Math.Cos(i)/Math.Cos(manuever.launchLat);
            double A = Math.Asin(sin_A);

            double ny = -Math.Cos(A);
            double nz = sin_A;

            double D = ny * ny + nz * nz * Math.Pow(Math.Sin(manuever.launchLat), 2);
            double sin_d = -(nz * Math.Cos(Omega) * Math.Sin(manuever.launchLat) + ny * Math.Sin(Omega)) * Math.Sin(i) / D;
            double cos_d = (nz * Math.Sin(Omega) * Math.Sin(manuever.launchLat) - ny * Math.Cos(Omega)) * Math.Sin(i) / D;

            double d = math.arg(sin_d, cos_d);
            double rotAngle_ref = d - manuever.launchLon;

            double omega = 2 * Math.PI / depData.rotationPeriod;
            double rotAngle = depBody.get_rotation_angle(manuever.startTime)*math.RAD;

            double dT = 0;

            if (rotAngle >= rotAngle_ref)
            {
                dT = (rotAngle - rotAngle_ref) / omega;
            }
            else
            {
                dT = 21600 - (rotAngle_ref - rotAngle) / omega;
            }

            manuever.launchTime = manuever.startTime - dT;
            KCalendar.sec_to_date(manuever.launchTime, ref manuever.launchDate);

            // Debug
            rotAngle = depBody.get_rotation_angle(manuever.launchTime)*math.RAD;

            // Relative azimuth calculation
            double vs = omega*R*Math.Cos(manuever.launchLat);
            double sin_Ar = (vk * sin_A - vs) / Math.Sqrt(vk * vk + vs * vs - 2 * vk * vs * sin_A);

            manuever.azimuth = Math.Asin(sin_Ar) / math.RAD;

            return true;
        }
Beispiel #2
0
        //---------------------------------------------------------------------
        //      Transfer dV calculation
        //---------------------------------------------------------------------
        public static void get_depatrure_manuever(CelestialBody depBody,                                                 
                                               CelestialBody craft,
                                               double t1,                                               
                                               ref DepManuever manuever)
        {
            OrbitPos depPos = new OrbitPos();

            depBody.get_position(t1, ref depPos);

            // Calculation SOI departure velocity
            Vector3D Vd = depBody.get_velocity(depPos.theta);

            Vector3D Vc = craft.get_velocity(0);

            Vector3D Vro = Vc - Vd;

            double v_ro = Vro.lenght();

            // Depatrure hyperbolic orbit calculation
            Vector3D x1 = depBody.get_cartesian_pos(depPos.theta);

            double u = 0;

            get_transfer_orientation(x1, Vro, ref manuever.orbit.i, ref manuever.orbit.Omega, ref u);

            if (manuever.orbit.i > 90.0)
            {
                manuever.orbit.i = 180.0 - manuever.orbit.i;
                manuever.orbit.Omega += 180.0;

                if (manuever.orbit.Omega > 360)
                    manuever.orbit.Omega -= 360;
            }

            // Eject dV calculation
            BodyData depData = new BodyData();

            depBody.get_data(ref depData);

            double ro = depData.sphereOfInfluence;
            double R = depData.radius;
            double mu = depData.gravParameter;
            double h = manuever.h;

            double v0 = Math.Sqrt(2 * mu * (1 / (R + h) - 1 / ro) + v_ro * v_ro);
            manuever.dv = v0 - Math.Sqrt(mu / (R + h));

            // Time of hyperbolic departure calculation
            double vk = Math.Sqrt(mu / (R + h));
            manuever.orbit.e = (v0 * v0 / vk / vk - 1);
            double p = (R + h) * (1 + manuever.orbit.e);
            double cos_theta = (p / ro - 1) / manuever.orbit.e;
            double theta = Math.Acos(cos_theta);
            manuever.orbit.a = p / (manuever.orbit.e * manuever.orbit.e - 1);
            double n = Math.Sqrt(mu / manuever.orbit.a) / manuever.orbit.a;
            double thH2 = Math.Sqrt((manuever.orbit.e - 1) / (manuever.orbit.e + 1)) * Math.Tan(theta / 2);
            double H = Math.Log((1 + thH2) / (1 - thH2));
            double M = manuever.orbit.e * Math.Sinh(H) - H;
            double dT = M / n;

            manuever.orbit.omega = (Math.Acos(1/manuever.orbit.e) - Math.PI/2) / math.RAD;

            // Low orbit wait time calculation
            double waitTime = manuever.turns * 2 * Math.PI * (R + h) / vk;

            manuever.ejectTime = t1 - dT;
            manuever.startTime = t1 - dT - waitTime;

            KCalendar.sec_to_date(manuever.ejectTime, ref manuever.ejectDate);
            KCalendar.sec_to_date(manuever.startTime, ref manuever.startDate);
        }
Beispiel #3
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        private void buttonHomanSearch_Click(object sender, EventArgs e)
        {
            double t0 = KCalendar.date_to_sec(int.Parse(textBeginYear.Text.ToString()),
                                            int.Parse(comboBeginDay.Text.ToString()),
                                            int.Parse(comboBeginHour.Text.ToString()),
                                            int.Parse(comboBeginMin.Text.ToString()),
                                            int.Parse(comboBeginSec.Text.ToString()));

            double t1 = KCalendar.date_to_sec(int.Parse(textEndYear.Text.ToString()),
                                            int.Parse(comboEndDay.Text.ToString()),
                                            int.Parse(comboEndHour.Text.ToString()),
                                            int.Parse(comboEndMin.Text.ToString()),
                                            int.Parse(comboEndSec.Text.ToString()));

            int dep_idx = get_body_index(comboHomanArrivList.Text.ToString());
            int arr_idx = get_body_index(comboHomanDepList.Text.ToString());

            // Check same reference body!!!
            if (Bodies[dep_idx].get_ref_body() != Bodies[arr_idx].get_ref_body())
            {
                labelNoTransfer.Text = "Bodies must have same reference body!\nPlease, change other bodies";
                return;
            }

            Transfer trans = new Transfer();

            double psi = Convert.ToDouble(textPsi.Text) * RAD;

            bool ready = Lambert.get_transfer_date(t0, t1, Bodies[dep_idx], Bodies[arr_idx], psi, ref trans);

            if (!ready)
            {
                panelHomanRes.Visible = false;
                labelNoTransfer.Text = "Transfer is imposible in changed period";
                return;
            }

            labelNoTransfer.Text = "";

            panelHomanRes.Visible = true;

            KDate deltaDate = new KDate();

            KCalendar.DeltaDate(trans.arrivTime - trans.depTime, ref deltaDate);

            labelArivDate.Text = trans.depDate.year.ToString() + "y " +
                                 trans.depDate.day.ToString() + "d " +
                                 trans.depDate.hour.ToString() + "h " +
                                 trans.depDate.min.ToString() + "m " +
                                 trans.depDate.sec.ToString() + "s";

            labelDepDate.Text = trans.arrivDate.year.ToString() + "y " +
                                 trans.arrivDate.day.ToString() + "d " +
                                 trans.arrivDate.hour.ToString() + "h " +
                                 trans.arrivDate.min.ToString() + "m " +
                                 trans.arrivDate.sec.ToString() + "s";

            labelTransTime.Text = deltaDate.year.ToString() + "y " +
                                 deltaDate.day.ToString() + "d " +
                                 deltaDate.hour.ToString() + "h " +
                                 deltaDate.min.ToString() + "m " +
                                 deltaDate.sec.ToString() + "s";

            labelSmiMajorAxis.Text = Math.Round(trans.orbit.a, 0).ToString() + " m";
            labelEccentricity.Text = Math.Round(trans.orbit.e, 4).ToString();
            labelInclination.Text = Math.Round(trans.orbit.i, 4).ToString() + " deg";
            labelLAN.Text = Math.Round(trans.orbit.Omega, 4).ToString() + " deg";
            labelArgPe.Text = Math.Round(trans.orbit.omega, 4).ToString() + " deg";

            CelestialBody craft = new CelestialBody();

            BodyData craft_data = new BodyData();

            craft_data.name = "Space craft";
            craft_data.orbit = trans.orbit;
            craft.set_data(ref craft_data);
            craft.set_refGravParameter(Bodies[dep_idx].get_refGravParameter());

            DepManuever manuever = new DepManuever();

            manuever.h = double.Parse(textAltitude.Text)*1000.0;
            manuever.turns = int.Parse(textWaitTurns.Text);

            Lambert.get_depatrure_manuever(Bodies[dep_idx],
                                           craft,
                                           trans.depTime,
                                           ref manuever);

            labelDeltaV.Text = Math.Round(manuever.dv, 2).ToString();
            labelInc.Text = Math.Round(manuever.orbit.i, 4).ToString();
            labelStartLAN.Text = Math.Round(manuever.orbit.Omega, 4).ToString();

            labelEjectDate.Text = manuever.ejectDate.year.ToString() + "y " +
                                  manuever.ejectDate.day.ToString() + "d " +
                                  manuever.ejectDate.hour.ToString() + "h " +
                                  manuever.ejectDate.min.ToString() + "m " +
                                  manuever.ejectDate.sec.ToString() + "s";

            double latDeg = double.Parse(textLatDeg.Text);
            double latMin = double.Parse(textLatMin.Text);
            double latSec = double.Parse(textLatSec.Text);

            double lonDeg = double.Parse(textLonDeg.Text);
            double lonMin = double.Parse(textLonMin.Text);
            double lonSec = double.Parse(textLonSec.Text);

            manuever.launchLat = (latDeg + latMin / 60.0 + latSec / 3600.0) * RAD;
            manuever.launchLon = (lonDeg + lonMin / 60.0 + lonSec / 3600.0) * RAD;

            if (radioButtonSouth.Checked)
                manuever.launchLat = -manuever.launchLat;

            if (radioButtonWest.Checked)
                manuever.launchLon = -manuever.launchLon;

            bool flag = Lambert.get_launch_params(Bodies[dep_idx], ref manuever);

            if (flag)
            {
                labelStartDate.Text = manuever.launchDate.year.ToString() + "y " +
                                      manuever.launchDate.day.ToString() + "d " +
                                      manuever.launchDate.hour.ToString() + "h " +
                                      manuever.launchDate.min.ToString() + "m " +
                                      manuever.launchDate.sec.ToString() + "s";

                labelAzimuth.Text = Math.Round(manuever.azimuth, 2).ToString();
            }

            // Draw trajectory
            DrawTransOrbit(panelTransOrbit, trans, Bodies[dep_idx], Bodies[arr_idx], craft);
        }