예제 #1
0
        // calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
        public moonRiseSet getMoonTimes(long date, double lat, double lng, bool inUTC)
        {
            long t = date;
            //            if (inUTC) t.setUTCHours(0, 0, 0, 0);
            //            else t.setHours(0, 0, 0, 0);

            double hc = 0.133 * rad;
            AltAz  gmp = getMoonPosition(t, lat, lng);
            double h0 = gmp.Alt - hc,
                   h1, h2, rise = 0.0, set = 0.0, a, b, xe, ye = 0.0, d, roots, x1 = 0.0, x2 = 0.0, dx;

            // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
            for (var i = 1; i <= 24; i += 2)
            {
                AltAz gmp1 = getMoonPosition(hoursLater(t, i), lat, lng);
                AltAz gmp2 = getMoonPosition(hoursLater(t, i + 1), lat, lng);
                h1 = gmp1.Alt - hc;
                h2 = gmp2.Alt - hc;

                a     = (h0 + h2) / 2 - h1;
                b     = (h2 - h0) / 2;
                xe    = -b / (2 * a);
                ye    = (a * xe + b) * xe + h1;
                d     = b * b - 4 * a * h1;
                roots = 0;
                x1    = 0.0;
                x2    = 0.0;
                if (d >= 0)
                {
                    dx = Math.Sqrt(d) / (Math.Abs(a) * 2);
                    x1 = xe - dx;
                    x2 = xe + dx;
                    if (Math.Abs(x1) <= 1)
                    {
                        roots++;
                    }
                    if (Math.Abs(x2) <= 1)
                    {
                        roots++;
                    }
                    if (x1 < -1)
                    {
                        x1 = x2;
                    }
                }

                if (roots == 1)
                {
                    if (h0 < 0)
                    {
                        rise = (double)i + x1;
                    }
                    else
                    {
                        set = i + x1;
                    }
                }
                else if (roots == 2)
                {
                    rise = i + (ye < 0 ? x2 : x1);
                    set  = i + (ye < 0 ? x1 : x2);
                }

                if (rise != 0.0 && set != 0.0)
                {
                    break;
                }

                h0 = h2;
            }

            var result = new moonRiseSet();

            if (rise != 0.0)
            {
                result.riseTime = hoursLater(t, (int)rise);
            }
            if (set != 0)
            {
                result.settime = hoursLater(t, (int)set);
            }
            if (rise == 0.0 && set == 0.0)
            {
                result.state = ye > 0 ? "alwaysUp" : "alwaysDown";
            }

            return(result);
        }
예제 #2
0
        //update position display
        private void updatePosition()
        {
            if ((DateTime.Now - messageTime).TotalSeconds > 30)
            {
                Message.Text = "";
            }

            //read actual form encoders
            //if (dev.Connected && state == DishState.Stopped)
            //{
            //    azPos = azReadPosition();
            //    elPos = elReadPosition();
            //}
            //set up display variables in deg, min, sec format
            GeoAngle AzAngle = GeoAngle.FromDouble(azPos, true);
            GeoAngle ElAngle = GeoAngle.FromDouble(elPos);

            //convert to RA/DEC
            RaDec astro = celestialConversion.CalcualteRaDec(elPos, azPos, settings.latitude, settings.longitude);
            //set up RA DEC as deg,min,sec
            GeoAngle Dec = GeoAngle.FromDouble(astro.Dec);
            GeoAngle RA  = GeoAngle.FromDouble(astro.RA, true);

            //log position every tenth time through
            string posLog = string.Format("RA {0:D3} : {1:D2}\t DEC {2:D3} : {3:D2}", RA.Degrees, RA.Minutes, Dec.Degrees, Dec.Minutes);

            currentIncrement++;
            if (currentIncrement % 9 == 0)
            {
                RollingLogger.LogMessage(posLog);
                currentIncrement = 0;
            }

            //show AZ, EL on main form
            this.Azimuth.Text   = string.Format("{0:D3} : {1:D2}", AzAngle.Degrees, AzAngle.Minutes);
            this.Elevation.Text = string.Format("{0:D2} : {1:D2}", ElAngle.Degrees, ElAngle.Minutes);

            //show RA,DEC on main form
            this.RA.Text  = string.Format("{0:D3} : {1:D2}", RA.Degrees, RA.Minutes);
            this.DEC.Text = string.Format("{0:D2} : {1:D2}", Dec.Degrees, Dec.Minutes);

            //if celestial track is set, check to make sure command position is above horizon if so then enable motion
            //probably have to have a completely seperate velocity track loop here - PID loop may not be satisfactor
            //-----NEEDS TESTING
            if (trackCelestial)
            {
                AltAz aa = celestialConversion.CalculateAltAz(RAcommand, decCommand, settings.latitude, settings.longitude);
                if (aa.Alt < 0)
                {
                    Message.Text   = "Requested position is below horizon!";
                    trackMoon      = false;
                    messageTime    = DateTime.Now;
                    trackCelestial = false;
                }
                GeoAngle cAzAngle = GeoAngle.FromDouble(aa.Az, true);
                GeoAngle cElAngle = GeoAngle.FromDouble(aa.Alt);
                azCommand           = aa.Az;
                elCommand           = aa.Alt;
                this.commandAz.Text = string.Format("{0:D3} : {1:D2}", cAzAngle.Degrees, cAzAngle.Minutes);
                this.commandEl.Text = string.Format("{0:D2} : {1:D2}", cElAngle.Degrees, cElAngle.Minutes);

                if (state != DishState.Moving && state != DishState.Tracking && aa.Alt > 1.0)
                {
                    this.Go();
                }
            }


            //if Lunar track is set, check to make sure Moon position is above horizon if so then enable motion
            //probably have to have a completely seperate velocity track loop here - PID loop may not be satisfactor
            //-----NEEDS TESTING
            if (trackMoon)
            {
                SunCalc sc    = new SunCalc();
                long    eDate = sc.epochDate(DateTime.UtcNow);
                double  jdate = sc.toJulian(eDate);
                AltAz   aa    = sc.getMoonPosition(eDate, settings.latitude, settings.longitude);
                if (aa.Alt < 0)
                {
                    Message.Text = "Moon is below horizon!";
                    trackMoon    = false;
                    messageTime  = DateTime.Now;
                }
                moonRiseSet mrs = sc.getMoonTimes(eDate, settings.latitude, settings.longitude, true);
                azCommand = aa.Az;
                elCommand = aa.Alt;
                GeoAngle mAzAngle = GeoAngle.FromDouble(aa.Az, true);
                GeoAngle mElAngle = GeoAngle.FromDouble(aa.Alt);
                this.commandAz.Text = string.Format("{0} : {1}", mAzAngle.Degrees, mAzAngle.Minutes);
                this.commandEl.Text = string.Format("{2}{0} : {1}", mElAngle.Degrees, mElAngle.Minutes, mElAngle.IsNegative ? "-" : "");

                double Alt = elCommand;
                if (Alt > 90.0)
                {
                    Alt = Alt - 90.0;
                }
                RaDec    mastro = celestialConversion.CalcualteRaDec(Alt, azCommand, settings.latitude, settings.longitude);
                GeoAngle mDec   = GeoAngle.FromDouble(mastro.Dec);
                GeoAngle mRA    = GeoAngle.FromDouble(mastro.RA, true);

                this.commandRA.Text  = string.Format("{0:D3} : {1:D2}", mRA.Degrees, mRA.Minutes);
                this.commandDec.Text = string.Format("{0:D2} : {1:D2}", mDec.Degrees, mDec.Minutes);
                if (state != DishState.Moving && state != DishState.Tracking && aa.Alt > 1.0)
                {
                    this.Go();
                }
            }//trackMoon

            //send stop command if we have to here
            if (state != DishState.Stopped && state != DishState.Unknown)
            {
                if (azPid.Complete && elPid.Complete)
                {
                    this.Stop();
                }
            }
        }