コード例 #1
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        private static string ToMountHex(Dms value)
        {
            var intval = (uint)(value.ValueMod * (uint.MaxValue + 1.0));

            intval &= 0xffffff00;
            return(intval.ToString("X8"));
        }
コード例 #2
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        private string FormatLatLon(Dms lat, Dms lon)
        {
            var(latSign, latDeg, latMin, latSec, _) = lat.DegreesMinutesSeconds;
            var(lonSign, lonDeg, lonMin, lonSec, _) = lon.DegreesMinutesSeconds;
            // The format of the location commands is: ABCDEFGH, where:
            // A is the number of degrees of latitude.
            // B is the number of minutes of latitude.
            // C is the number of seconds of latitude.
            // D is 0 for north and 1 for south.
            // E is the number of degrees of longitude.
            // F is the number of minutes of longitude.
            // G is the number of seconds of longitude.
            // H is 0 for east and 1 for west.
            var builder = new StringBuilder(8);

            builder.Append((char)latDeg);
            builder.Append((char)latMin);
            builder.Append((char)latSec);
            builder.Append(latSign ? (char)1 : (char)0);
            builder.Append((char)lonDeg);
            builder.Append((char)lonMin);
            builder.Append((char)lonSec);
            builder.Append(lonSign ? (char)1 : (char)0);
            return(builder.ToString());
        }
コード例 #3
0
ファイル: PlateSolve.cs プロジェクト: WasatchPhotonics/scopie
        private static async Task <(Dms ra, Dms dec)?> SolveOne(string filename)
        {
            var low        = 0.9;
            var high       = 1.1;
            var downsample = 4;
            var info       = new ProcessStartInfo(_bashLocation, BuildCommand(low, high, downsample, filename))
            {
                UseShellExecute        = false,
                RedirectStandardOutput = true,
            };
            var process = Process.Start(info);
            var output  = await process.StandardOutput.ReadToEndAsync();

            var matches = _regex.Match(output);

            if (matches.Success)
            {
                var one = matches.Groups[1].Value;
                var two = matches.Groups[2].Value;
                if (double.TryParse(one, out var oneValue) && double.TryParse(two, out var twoValue))
                {
                    return(Dms.FromDegrees(oneValue), Dms.FromDegrees(twoValue));
                }
            }
            return(null);
        }
コード例 #4
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task SlewAzAlt(Dms az, Dms alt)
        {
            var res = await Interact($"b{ToMountHex(az)},{ToMountHex(alt)}");

            if (res != "")
            {
                throw new Exception($"Slew az/alt failed: {res}");
            }
        }
コード例 #5
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task Slew(Dms ra, Dms dec)
        {
            var res = await Interact($"r{ToMountHex(ra)},{ToMountHex(dec)}");

            if (res != "")
            {
                throw new Exception($"Slew RA/DEC failed: {res}");
            }
        }
コード例 #6
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task OverwriteRaDec(Dms ra, Dms dec)
        {
            var res = await Interact($"s{ToMountHex(ra)},{ToMountHex(dec)}");

            if (res != "")
            {
                throw new Exception($"Overwrite RA/DEC failed: {res}");
            }
        }
コード例 #7
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task SetLocation(Dms lat, Dms lon)
        {
            var location = FormatLatLon(lat, lon);
            var result   = await Interact($"W{location}");

            if (result != "")
            {
                throw new Exception($"Set location failed: {result}");
            }
        }
コード例 #8
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        static void SplitThreeBytes(Dms valueDms, out byte high, out byte med, out byte low)
        {
            var value = valueDms.ValueMod;

            value *= 256;
            high   = (byte)value;
            value  = Dms.Mod(value, 1);
            value *= 256;
            med    = (byte)value;
            value  = Dms.Mod(value, 1);
            value *= 256;
            low    = (byte)value;
        }
コード例 #9
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        async Task PCommandThree(byte one, byte two, byte three, Dms data)
        {
            SplitThreeBytes(data, out var high, out var med, out var low);
            var cmd = new char[8];

            cmd[0] = 'P';
            cmd[1] = (char)one;
            cmd[2] = (char)two;
            cmd[3] = (char)three;
            cmd[4] = (char)high;
            cmd[5] = (char)med;
            cmd[6] = (char)low;
            cmd[7] = (char)0;
            await Interact(new string(cmd));
        }
コード例 #10
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task <(Dms, Dms)> GetAzAlt()
        {
            var line = await Interact("z");

            var split = line.Split(',');

            if (split.Length != 2)
            {
                throw new Exception($"Invalid response to 'z': {line}");
            }
            var az  = Convert.ToUInt32(split[0], 16) / (uint.MaxValue + 1.0);
            var alt = Convert.ToUInt32(split[1], 16) / (uint.MaxValue + 1.0);

            return(Dms.From0to1(az), Dms.From0to1(alt));
        }
コード例 #11
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        public async Task <(Dms, Dms)> GetRaDec()
        {
            var line = await Interact("e");

            var split = line.Split(',');

            if (split.Length != 2)
            {
                throw new Exception($"Invalid response to 'e': {line}");
            }
            var ra  = Convert.ToUInt32(split[0], 16) / (uint.MaxValue + 1.0);
            var dec = Convert.ToUInt32(split[1], 16) / (uint.MaxValue + 1.0);

            return(Dms.From0to1(ra), Dms.From0to1(dec));
        }
コード例 #12
0
ファイル: Dms.cs プロジェクト: WasatchPhotonics/scopie
        public static bool TryParse(string s, out Dms dms)
        {
            var match = _parseRegex.Match(s);

            if (!match.Success)
            {
                dms = default;
                return(false);
            }
            var signMatch    = match.Groups["sign"];
            var isNegative   = signMatch.Success ? signMatch.Value == "-" : false;
            var degrees      = double.Parse(match.Groups["degrees"].Value);
            var minutesMatch = match.Groups["minutes"];
            var minutes      = minutesMatch.Success ? double.Parse(minutesMatch.Value) : 0;
            var secondsMatch = match.Groups["seconds"];
            var seconds      = secondsMatch.Success ? double.Parse(secondsMatch.Value) : 0;
            var unitMatch    = match.Groups["unit"];

            if (unitMatch.Success)
            {
                if (unitMatch.Value == "h" || unitMatch.Value == "H")
                {
                    dms = FromHms(isNegative, degrees, minutes, seconds);
                }
                else
                {
                    dms = FromDms(isNegative, degrees, minutes, seconds);
                }
            }
            else
            {
                if (double.TryParse(s, out var rawValue))
                {
                    dms = From0to1(rawValue);
                    if (rawValue < 0 || rawValue > 1)
                    {
                        Console.WriteLine("Got a value outside [0,1] for raw value - did you mean to add a unit? e.g. " + s + "d for degrees");
                        return(false);
                    }
                }
                else
                {
                    throw new Exception("Missing unit, but didn't parse as double: " + s);
                }
            }
            return(true);
        }
コード例 #13
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
        private (Dms, Dms) ParseLatLon(string value)
        {
            if (value.Length != 8)
            {
                throw new Exception($"Invalid lat/lon: {value}");
            }
            var latDeg  = (int)value[0];
            var latMin  = (int)value[1];
            var latSec  = (int)value[2];
            var latSign = value[3] == 1;
            var lonDeg  = (int)value[4];
            var lonMin  = (int)value[5];
            var lonSec  = (int)value[6];
            var lonSign = value[7] == 1;
            var lat     = Dms.FromDms(latSign, latDeg, latMin, latSec);
            var lon     = Dms.FromDms(lonSign, lonDeg, lonMin, lonSec);

            return(lat, lon);
        }
コード例 #14
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
 public Task SlowGotoDec(Dms data) => PCommandThree(4, 17, 23, data);
コード例 #15
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
 public Task SlowGotoRA(Dms data) => PCommandThree(4, 16, 23, data);
コード例 #16
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
 public Task ResetDec(Dms data) => PCommandThree(4, 17, 4, data);
コード例 #17
0
ファイル: Mount.cs プロジェクト: WasatchPhotonics/scopie
 public Task ResetRA(Dms data) => PCommandThree(4, 16, 4, data);
コード例 #18
0
        private static async Task ReplMount(string[] cmd, Mount mount)
        {
            switch (cmd[0])
            {
            case "help":
                Console.WriteLine("slew [ra] [dec] - slew to direction");
                Console.WriteLine("slewra [ra] - slow goto");
                Console.WriteLine("slewdec [dec] - slow goto");
                Console.WriteLine("cancel - cancel slew");
                Console.WriteLine("pos - get current direction");
                Console.WriteLine("setpos - overwrite current direction");
                Console.WriteLine("syncpos - sync/calibrate current direction");
                Console.WriteLine("azalt - get current az/alt");
                Console.WriteLine("azalt [az] [alt] - slew to az/alt");
                Console.WriteLine("track - get tracking mode");
                Console.WriteLine("track [value] - set tracking mode");
                Console.WriteLine("location - get lat/lon");
                Console.WriteLine("location [lat] [lon] - set lat/lon");
                Console.WriteLine("time - get mount's time");
                Console.WriteLine("time now - set mount's time to now");
                Console.WriteLine("aligned - get true/false if mount is aligned");
                Console.WriteLine("ping - ping mount, prints time it took");
                Console.WriteLine("solve [filename] - plate-solve image with ANSVR");
                break;

            case "slew":
            {
                cmd[1] = cmd[1].TrimEnd(',');
                if (cmd.Length == 3 && Dms.TryParse(cmd[1], out var ra) && Dms.TryParse(cmd[2], out var dec))
                {
                    await mount.Slew(ra, dec);
                }
                else
                {
                    goto default;
                }
            }
            break;

            case "slewra":
            {
                if (cmd.Length == 2 && Dms.TryParse(cmd[1], out var ra))
                {
                    await mount.SlowGotoRA(ra);
                }
                else
                {
                    goto default;
                }
            }
            break;

            case "slewdec":
            {
                if (cmd.Length == 2 && Dms.TryParse(cmd[1], out var ra))
                {
                    await mount.SlowGotoDec(ra);
                }
                else
                {
                    goto default;
                }
            }
            break;

            case "cancel":
                await mount.CancelSlew();

                break;

            case "pos":
            {
                var(ra, dec) = await mount.GetRaDec();

                Console.WriteLine($"{ra.ToDmsString(Dms.Unit.Hours)}, {dec.ToDmsString(Dms.Unit.Degrees)}");
            }
            break;

            case "setpos":
            {
                cmd[1] = cmd[1].TrimEnd(',');
                if (cmd.Length == 3 && Dms.TryParse(cmd[1], out var ra) && Dms.TryParse(cmd[2], out var dec))
                {
                    await mount.ResetRA(ra);

                    await mount.ResetDec(dec);
                }
                else
                {
                    goto default;
                }
            }
            break;

            case "syncpos":
            {
                cmd[1] = cmd[1].TrimEnd(',');
                if (cmd.Length == 3 && Dms.TryParse(cmd[1], out var ra) && Dms.TryParse(cmd[2], out var dec))
                {
                    await mount.OverwriteRaDec(ra, dec);
                }
                else
                {
                    goto default;
                }
            }
            break;

            case "azalt":
                if (cmd.Length == 1)
                {
                    var(az, alt) = await mount.GetAzAlt();

                    Console.WriteLine($"{az.ToDmsString(Dms.Unit.Degrees)}, {alt.ToDmsString(Dms.Unit.Degrees)}");
                }
                else if (cmd.Length == 3 && Dms.TryParse(cmd[1], out var az) && Dms.TryParse(cmd[2], out var alt))
                {
                    await mount.SlewAzAlt(az, alt);
                }
                else
                {
                    goto default;
                }
                break;

            case "track":
                if (cmd.Length == 1)
                {
                    var track = await mount.GetTrackingMode();

                    Console.WriteLine($"Mode: {track}");
                    Console.WriteLine($"(available: {string.Join(", ", (Mount.TrackingMode[])Enum.GetValues(typeof(Mount.TrackingMode)))})");
                }
                else if (cmd.Length == 2 && Enum.TryParse <Mount.TrackingMode>(cmd[1], out var mode))
                {
                    await mount.SetTrackingMode(mode);
                }
                else
                {
                    goto default;
                }
                break;

            case "location":
                if (cmd.Length == 1)
                {
                    var(lat, lon) = await mount.GetLocation();

                    Console.WriteLine($"{lat.ToDmsString(Dms.Unit.Degrees)}, {lon.ToDmsString(Dms.Unit.Degrees)}");
                }
                else if (cmd.Length == 3 && Dms.TryParse(cmd[1], out var lat) && Dms.TryParse(cmd[2], out var lon))
                {
                    await mount.SetLocation(lat, lon);
                }
                else
                {
                    goto default;
                }
                break;

            case "time":
                if (cmd.Length == 1)
                {
                    var now_one = DateTime.Now;
                    var time    = await mount.GetTime();

                    Console.WriteLine($"Mount time: {time} (off by {now_one - time})");
                }
                else if (cmd.Length == 2 && cmd[1] == "now")
                {
                    await mount.SetTime(DateTime.Now);
                }
                else
                {
                    goto default;
                }
                break;

            case "aligned":
            {
                var aligned = await mount.IsAligned();

                Console.WriteLine($"IsAligned: {aligned}");
            }
            break;

            case "ping":
            {
                var timer = Stopwatch.StartNew();
                var res   = await mount.Echo('p');

                Console.WriteLine($"{timer.ElapsedMilliseconds}ms");
            }
            break;

            case "solve":
                if (cmd.Length == 2)
                {
                    var task = PlateSolve.SolveFile(cmd[1]);
                }
                else
                {
                    goto default;
                }
                break;

            default:
                Console.WriteLine($"Unknown command {string.Join(" ", cmd)}");
                break;
            }
        }