Merged in develop (pull request #4)

Develop

* Removed unwanted files

* Adding git ignore file

* Started working on getting the basic communications with the scope working.
    Working on routines to get and set the date and time in the handbox.

* Switched the serial port over to using the .net frameworks serial port.
    Extracted the serial port into it's own class and created a simpler command processing mechanism.

* Implemented AbortSlew and did some code tidy up.

* Forced all code to 64-bit only, will make this 32/64 bit before release.
    Fixed issue in the SerialProcessor when setting the time, makes sure that there's no chance of thread stealing when pulling out the junk messages
    Added ConformanceResult.txt to show the progress of the driver development

* Added code for the site latitude
    and started work on the longitude.

* Added unit tests for reading and writing the utcDate.
    Fixed a couple of defects in the code that was setting the utcDate.

* Corrected Longitude value range

* Added support for UTC offset.

* Pulse guiding support added

* Added SiteLatitude unit tests

* Added unit tests for SiteLongitude

* Added unit tests for the new Pulse guide implementation.

* Added support for AlignmentMode

* Added support for AtPark and Park

* Added support for parking the scope
    Added support for reading the scope Azimuth

* Added support for reading Declination

* Added 5 second timeout for the serial port.
    Fixed problem with the GW command not working on the Autostar 497.

* Fixed broken unit test

* Added support for altitude

* Tidying up resharper warinings

* Implemented RightAscension
    TargetRightAscension
    TargetDec
    SlewToCoord
    and SlewToCoordAsync

* Sorted out the target RA and Dec exceptions to be compliant with ascom.

* Implemented SlewToAltAz and SlewToAltAzAsync

* Implemented SyncToTarget functionality

* Implemented slew to target

* Added support for MoveAxis

* Added support for tracking rate

* Added IFocuserV3 to the driver and made sure that it's registered for ASCOM as a focuser as well.

* Fixed issue with Target RA and Dec loosing precision

* Telescope driver now passes the Ascom conformance.

* Upgraded driver version to 0.1

* Added explicit locks around all sequences of commands.

* Basic implementation of the IFocusserV3

* Focuser passes validation, this makes the code V0.2

Approved-by: Colin Dawson <me@cjdawson.com>
This commit is contained in:
2019-05-13 23:46:50 +00:00
parent 777adb260a
commit 2a97d151a4
7 changed files with 385 additions and 150 deletions
+260 -136
View File
@@ -97,6 +97,7 @@ namespace ASCOM.MeadeAutostar497.Controller
SerialPort.Open();
TestConnectionActive();
SetFocuserSpeedFastest();
}
catch (Exception)
{
@@ -520,6 +521,10 @@ namespace ASCOM.MeadeAutostar497.Controller
}
}
public int FocuserMaxIncrement { get; set; } = 7000;
public int FocuserMaxStep { get; set; } = 7000;
public double Altitude {
get
{
@@ -562,14 +567,22 @@ namespace ASCOM.MeadeAutostar497.Controller
}
else
{
_serialPort.Command(":RG#"); //Make sure we are at guide rate
_serialPort.Command($":M{d}#");
Thread.Sleep(duration);
_serialPort.Command($":Q{d}#");
SerialPort.Lock();
try
{
_serialPort.Command(":RG#"); //Make sure we are at guide rate
_serialPort.Command($":M{d}#");
Thread.Sleep(duration);
_serialPort.Command($":Q{d}#");
//classic only !!!, this is needed since once in a while one is not enough
Thread.Sleep(200);
_serialPort.Command($":Q{d}#");
//classic only !!!, this is needed since once in a while one is not enough
Thread.Sleep(200);
_serialPort.Command($":Q{d}#");
}
finally
{
SerialPort.Unlock();
}
}
}
@@ -594,10 +607,18 @@ namespace ASCOM.MeadeAutostar497.Controller
public void SlewToCoordinatesAsync(double rightAscension, double declination)
{
TargetRightAscension = rightAscension;
TargetDeclination = declination;
SerialPort.Lock();
try
{
TargetRightAscension = rightAscension;
TargetDeclination = declination;
DoSlewAsync(true);
DoSlewAsync(true);
}
finally
{
SerialPort.Unlock();
}
}
public void SlewToAltAz(double azimuth, double altitude)
@@ -663,10 +684,18 @@ namespace ASCOM.MeadeAutostar497.Controller
public void SlewToAltAzAsync(double azimuth, double altitude)
{
TargetAltitude = altitude;
TargetAzimuth = azimuth;
SerialPort.Lock();
try
{
TargetAltitude = altitude;
TargetAzimuth = azimuth;
DoSlewAsync(false);
DoSlewAsync(false);
}
finally
{
SerialPort.Unlock();
}
}
public void SyncToTarget()
@@ -706,145 +735,240 @@ namespace ASCOM.MeadeAutostar497.Controller
private bool _movingPrimary;
private bool _movingSecondary;
public void MoveAxis(TelescopeAxes axis, double rate)
{
var absrate = Math.Abs(rate);
switch(absrate)
SerialPort.Lock();
try
{
case 0:
//do nothing, it's ok this time as we're halting the slew.
break;
case 1:
SerialPort.Command(":RG#");
//:RG# Set Slew rate to Guiding Rate (slowest)
//Returns: Nothing
break;
case 2:
SerialPort.Command(":RC#");
//:RC# Set Slew rate to Centering rate (2nd slowest)
//Returns: Nothing
break;
case 3:
SerialPort.Command(":RM#");
//:RM# Set Slew rate to Find Rate (2nd Fastest)
//Returns: Nothing
break;
case 4:
SerialPort.Command(":RS#");
//:RS# Set Slew rate to max (fastest)
//Returns: Nothing
break;
default:
throw new ASCOM.InvalidValueException($"Rate {rate} not supported");
var absrate = Math.Abs(rate);
switch (absrate)
{
case 0:
//do nothing, it's ok this time as we're halting the slew.
break;
case 1:
SerialPort.Command(":RG#");
//:RG# Set Slew rate to Guiding Rate (slowest)
//Returns: Nothing
break;
case 2:
SerialPort.Command(":RC#");
//:RC# Set Slew rate to Centering rate (2nd slowest)
//Returns: Nothing
break;
case 3:
SerialPort.Command(":RM#");
//:RM# Set Slew rate to Find Rate (2nd Fastest)
//Returns: Nothing
break;
case 4:
SerialPort.Command(":RS#");
//:RS# Set Slew rate to max (fastest)
//Returns: Nothing
break;
default:
throw new ASCOM.InvalidValueException($"Rate {rate} not supported");
}
switch (axis)
{
case TelescopeAxes.axisPrimary:
if (rate == 0)
{
_movingPrimary = false;
SerialPort.Command(":Qe#");
//:Qe# Halt eastward Slews
//Returns: Nothing
SerialPort.Command(":Qw#");
//:Qw# Halt westward Slews
//Returns: Nothing
}
else if (rate > 0)
{
SerialPort.Command(":Me#");
//:Me# Move Telescope East at current slew rate
//Returns: Nothing
_movingPrimary = true;
}
else
{
SerialPort.Command(":Mw#");
//:Mw# Move Telescope West at current slew rate
//Returns: Nothing
_movingPrimary = true;
}
break;
case TelescopeAxes.axisSecondary:
if (rate == 0)
{
_movingSecondary = false;
SerialPort.Command(":Qn#");
//:Qn# Halt northward Slews
//Returns: Nothing
SerialPort.Command(":Qs#");
//:Qs# Halt southward Slews
//Returns: Nothing
}
else if (rate > 0)
{
SerialPort.Command(":Mn#");
//:Mn# Move Telescope North at current slew rate
//Returns: Nothing
_movingSecondary = true;
}
else
{
SerialPort.Command(":Ms#");
//:Ms# Move Telescope South at current slew rate
//Returns: Nothing
_movingSecondary = true;
}
break;
default:
throw new ASCOM.MethodNotImplementedException("Can not move this axis.");
}
}
finally
{
SerialPort.Unlock();
}
}
public void FocuserHalt()
{
SerialPort.Command(":FQ#");
//:FQ# Halt Focuser Motion
//Returns: Nothing
}
public void FocuserMove(int newPosition)
{
//todo implement backlash compensation
//todo implement direction reverse
//todo implement dynamic braking
if (newPosition < -FocuserMaxIncrement || newPosition > FocuserMaxIncrement)
{
throw new ASCOM.InvalidValueException($"position out of range {-FocuserMaxIncrement} < {newPosition} < {FocuserMaxIncrement}");
}
switch (axis)
{
case TelescopeAxes.axisPrimary:
if (rate == 0)
{
_movingPrimary = false;
SerialPort.Command(":Qe#");
//:Qe# Halt eastward Slews
//Returns: Nothing
SerialPort.Command(":Qw#");
//:Qw# Halt westward Slews
//Returns: Nothing
}
else if (rate > 0)
{
SerialPort.Command(":Me#");
//:Me# Move Telescope East at current slew rate
//Returns: Nothing
_movingPrimary = true;
}
else
{
SerialPort.Command(":Mw#");
//:Mw# Move Telescope West at current slew rate
//Returns: Nothing
_movingPrimary = true;
}
break;
case TelescopeAxes.axisSecondary:
if (rate == 0)
{
_movingSecondary = false;
SerialPort.Command(":Qn#");
//:Qn# Halt northward Slews
//Returns: Nothing
SerialPort.Command(":Qs#");
//:Qs# Halt southward Slews
//Returns: Nothing
}
else if (rate > 0)
{
SerialPort.Command(":Mn#");
//:Mn# Move Telescope North at current slew rate
//Returns: Nothing
_movingSecondary = true;
}
else
{
SerialPort.Command(":Ms#");
//:Ms# Move Telescope South at current slew rate
//Returns: Nothing
_movingSecondary = true;
}
if (newPosition == 0)
return;
break;
default:
throw new ASCOM.MethodNotImplementedException("Can not move this axis.");
if (newPosition > 0)
{
//desired move direction is out
MoveFocuser(true, Math.Abs(newPosition));
}
else
{
//desired move direction is in
MoveFocuser(false, Math.Abs(newPosition));
}
}
private void MoveFocuser(bool directionOut, int steps)
{
SerialPort.Command(directionOut ? ":F+#" : ":F-#");
//:F+# Start Focuser moving inward (toward objective)
//Returns: None
//:F-# Start Focuser moving outward (away from objective)
//Returns: None
Util.WaitForMilliseconds(steps);
FocuserHalt();
}
private void SetFocuserSpeedFastest()
{
SerialPort.Command(":FF#");
//:FF# Set Focus speed to fastest setting
//Returns: Nothing
}
private void SetFocuserSpeedSlowest()
{
SerialPort.Command(":FS#");
//:FS# Set Focus speed to slowest setting
//Returns: Nothing
}
private void SetFocuserSpeed( int speed)
{
if (speed < 1)
throw new ArgumentOutOfRangeException("speed is too low");
if (speed > 4)
throw new ArgumentOutOfRangeException("speed is too high");
SerialPort.Command($":F{speed}#");
//:F<n># Autostar, Autostar II set focuser speed to <n> where <n> is an ASCII digit 1..4
//Returns: Nothing
//All others Not Supported
}
//todo remove the polar parameter and split method into two.
private void DoSlewAsync( bool polar)
{
switch (polar)
SerialPort.Lock();
try
{
case true:
var response = SerialPort.CommandChar(":MS#");
//:MS# Slew to Target Object
//Returns:
//0 Slew is Possible
//1<string># Object Below Horizon w/string message
//2<string># Object Below Higher w/string message
switch (polar)
{
case true:
var response = SerialPort.CommandChar(":MS#");
//:MS# Slew to Target Object
//Returns:
//0 Slew is Possible
//1<string># Object Below Horizon w/string message
//2<string># Object Below Higher w/string message
switch (response)
{
case '0':
//We're slewing everything should be working just fine.
break;
case '1':
//Below Horizon
string belowHorizonMessage = SerialPort.ReadTerminated("#");
throw new ASCOM.InvalidOperationException(belowHorizonMessage);
case '2':
//Below Horizon
string belowMinimumElevationMessage = SerialPort.ReadTerminated("#");
throw new ASCOM.InvalidOperationException(belowMinimumElevationMessage);
default:
throw new ASCOM.DriverException("This error should not happen");
switch (response)
{
case '0':
//We're slewing everything should be working just fine.
break;
case '1':
//Below Horizon
string belowHorizonMessage = SerialPort.ReadTerminated("#");
throw new ASCOM.InvalidOperationException(belowHorizonMessage);
case '2':
//Below Horizon
string belowMinimumElevationMessage = SerialPort.ReadTerminated("#");
throw new ASCOM.InvalidOperationException(belowMinimumElevationMessage);
default:
throw new ASCOM.DriverException("This error should not happen");
}
break;
case false:
var maResponse = SerialPort.CommandChar(":MA#");
//:MA# Autostar, LX 16”, Autostar II Slew to target Alt and Az
//Returns:
//0 - No fault
//1 Fault
// LX200 Not supported
}
if (maResponse == '1')
{
throw new ASCOM.InvalidOperationException("fault");
}
break;
}
break;
case false:
var maResponse = SerialPort.CommandChar(":MA#");
//:MA# Autostar, LX 16”, Autostar II Slew to target Alt and Az
//Returns:
//0 - No fault
//1 Fault
// LX200 Not supported
if (maResponse == '1')
{
throw new ASCOM.InvalidOperationException("fault");
}
break;
}
}
finally
{
SerialPort.Unlock();
}
}
public bool UserNewerPulseGuiding { get; set; } = true; //todo make this a device setting