using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ArdupilotMega.Antenna { class Maestro : ITrackerOutput { public Comms.SerialPort ComPort { get; set; } /// /// 0-360 /// public double TrimPan { get; set; } /// /// -90 - 90 /// public double TrimTilt { get; set; } public int PanStartRange { get; set; } public int TiltStartRange { get; set; } public int PanEndRange { get; set; } public int TiltEndRange { get; set; } public int PanPWMRange { get; set; } public int TiltPWMRange { get; set; } public bool PanReverse { get { return _panreverse == -1; } set { _panreverse = value == true ? -1 : 1; } } public bool TiltReverse { get { return _tiltreverse == -1; } set { _tiltreverse = value == true ? -1 : 1; } } int _panreverse = 1; int _tiltreverse = 1; byte PanAddress = 0; byte TiltAddress = 1; public bool Init() { if ((PanStartRange - PanEndRange) == 0) { System.Windows.Forms.CustomMessageBox.Show("Invalid Pan Range", "Error"); return false; } if ((TiltStartRange - TiltEndRange) == 0) { System.Windows.Forms.CustomMessageBox.Show("Invalid Tilt Range", "Error"); return false; } try { ComPort.Open(); } catch (Exception ex) { System.Windows.Forms.CustomMessageBox.Show("Connect failed " + ex.Message, "Error"); return false; } return true; } public bool Setup() { int target = 100; // speed var buffer = new byte[] { 0x87, PanAddress, (byte)(target & 0x7F), (byte)((target >> 7) & 0x7F) }; ComPort.Write(buffer, 0, buffer.Length); buffer = new byte[] { 0x87, TiltAddress, (byte)(target & 0x7F), (byte)((target >> 7) & 0x7F) }; ComPort.Write(buffer, 0, buffer.Length); // accel target = 5; buffer = new byte[] { 0x89, PanAddress, (byte)(target & 0x7F), (byte)((target >> 7) & 0x7F) }; ComPort.Write(buffer, 0, buffer.Length); buffer = new byte[] { 0x89, TiltAddress, (byte)(target & 0x7F), (byte)((target >> 7) & 0x7F) }; ComPort.Write(buffer, 0, buffer.Length); return true; } double wrap_180(double input) { if (input > 180) return input - 360; if (input < -180) return input + 360; return input; } double wrap_range(double input, double range) { if (input > range) return input - 360; if (input < -range) return input + 360; return input; } public bool Pan(double Angle) { double range = Math.Abs(PanStartRange - PanEndRange); // get relative center based on tracking center double rangeleft = PanStartRange - TrimPan; double rangeright = PanEndRange - TrimPan; double centerpos = 127; // get the output angle the tracker needs to point and constrain the output to the allowed options short PointAtAngle = Constrain(wrap_180(Angle - TrimPan), PanStartRange, PanEndRange); // conver the angle into a 0-255 value byte target = (byte)((((PointAtAngle / range) * 2.0) * 127 + centerpos) * _panreverse); Console.WriteLine("P " + Angle + " " + target + " " + PointAtAngle); var buffer = new byte[] { 0xff, PanAddress, target }; ComPort.Write(buffer, 0, buffer.Length); return true; } public bool Tilt(double Angle) { double range = Math.Abs(TiltStartRange - TiltEndRange); short PointAtAngle = Constrain((Angle - TrimTilt), TiltStartRange, TiltEndRange); byte target = (byte)((((PointAtAngle / range) * 2) * 127 + 127) * _tiltreverse); //Console.WriteLine("T " + Angle + " " + target + " " + PointAtAngle); var buffer = new byte[] { 0xff, TiltAddress, target }; ComPort.Write(buffer, 0, buffer.Length); return true; } public bool PanAndTilt(double pan, double tilt) { if (Tilt(tilt) && Pan(pan)) return true; return false; } public bool Close() { try { ComPort.Close(); } catch { } return true; } short Constrain(double input, double min, double max) { if (input < min) return (short)min; if (input > max) return (short)max; return (short)input; } } }