diff --git a/NINA.Core/Enum/MountTypeEnum.cs b/NINA.Core/Enum/MountTypeEnum.cs
index 2508d7504..62d3d3106 100644
--- a/NINA.Core/Enum/MountTypeEnum.cs
+++ b/NINA.Core/Enum/MountTypeEnum.cs
@@ -30,5 +30,8 @@ public enum MountTypeEnum {
[Description("LblForkOnWedge")]
FORK_ON_WEDGE,
+
+ [Description("LblAltitudeAzimuth")]
+ ALT_AZ,
}
}
\ No newline at end of file
diff --git a/NINA.Core/Locale/Locale.resx b/NINA.Core/Locale/Locale.resx
index 2ff24033e..8e295b273 100644
--- a/NINA.Core/Locale/Locale.resx
+++ b/NINA.Core/Locale/Locale.resx
@@ -3899,7 +3899,7 @@ In case a longer duration is needed, a duration can be specified and the applica
GEM Axis Length
- If Alt/Az, this should be 0. For an EQ mount, slew RA to +/- 90 degrees, and measure the lateral distance (in mm) from the axis to center of the telescope aperture
+ On an EQ mount, slew RA to +/- 90 degrees, and measure the lateral distance (in mm) from the axis to center of the telescope aperture
Lateral Axis Length
@@ -7185,6 +7185,15 @@ Additionally, it is essential that the ASCOM driver used also supports this 32-b
Civil dawn
+
+ Altitude-Azimuth
+
+
+ Vertical axis length
+
+
+ For piggy-backed OTAs on an Alt-Az mounted telescope. This should be the distance between the center of the main OTA and the piggy-backed OTA
+
Refuse mount unpark if shutter is not open
diff --git a/NINA.Equipment/Equipment/MyDome/DomeSynchronization.cs b/NINA.Equipment/Equipment/MyDome/DomeSynchronization.cs
index b176c8744..6531bd9a9 100644
--- a/NINA.Equipment/Equipment/MyDome/DomeSynchronization.cs
+++ b/NINA.Equipment/Equipment/MyDome/DomeSynchronization.cs
@@ -24,8 +24,8 @@ This Source Code Form is subject to the terms of the Mozilla Public
namespace NINA.Equipment.Equipment.MyDome {
public class DomeSynchronization : IDomeSynchronization {
- private static double TWO_PI = 2.0 * Math.PI;
- private static double HALF_PI = Math.PI / 2.0;
+ private const double TWO_PI = 2.0 * Math.PI;
+ private const double HALF_PI = Math.PI / 2.0;
private readonly IProfileService profileService;
@@ -43,7 +43,6 @@ public TopocentricCoordinates TargetDomeCoordinates(
return TargetDomeCoordinates(scopeCoordinates: scopeCoordinates, localSiderealTime: localSiderealTime, siteLatitude: siteLatitude, siteLongitude: siteLongitude, siteElevation: 0, sideOfPier: sideOfPier);
}
-
///
/// Gets the dome coordinates required so the scope points directly out of the shutter. This works for Alt-Az, EQ mounts, and fork mounts on a wedge
/// and depends on careful user measurements including:
@@ -77,16 +76,17 @@ public TopocentricCoordinates TargetDomeCoordinates(
PierSide sideOfPier) {
scopeCoordinates = scopeCoordinates.Transform(Epoch.JNOW);
var domeSettings = profileService.ActiveProfile.DomeSettings;
+
// To calculate the effect of rotations in the southern hemisphere we augment a few of the rotations to pretend as if it were the northern hemisphere,
// and then add 180 degrees to the final result
-
var origin = new Vector4(0, 0, 0, 1);
- Matrix4x4 scopeOriginTranslation;
- if (domeSettings.MountType == MountTypeEnum.EQUATORIAL) {
- scopeOriginTranslation = CalculateGEM(scopeCoordinates, localSiderealTime, siteLatitude, sideOfPier);
- } else {
- scopeOriginTranslation = CalculateForkOnWedge(scopeCoordinates, localSiderealTime, siteLatitude);
- }
+
+ var scopeOriginTranslation = domeSettings.MountType switch {
+ MountTypeEnum.EQUATORIAL => CalculateGEM(scopeCoordinates, localSiderealTime, siteLatitude, sideOfPier),
+ MountTypeEnum.FORK_ON_WEDGE => CalculateForkOnWedge(scopeCoordinates, localSiderealTime, siteLatitude),
+ MountTypeEnum.ALT_AZ => CalculateAltAz(scopeCoordinates, siteLatitude, siteLongitude),
+ _ => throw new NotSupportedException($"Unsupported mount type: {domeSettings.MountType}"),
+ };
var scopeApertureOrigin = scopeOriginTranslation * origin;
@@ -207,5 +207,43 @@ private Matrix4x4 CalculateGEM(
return mountOffset * latitudeAdjustment * raRotationAdjustment * decRotationAdjustment * gemAdjustment;
}
+
+ private Matrix4x4 CalculateAltAz(
+ Coordinates scopeCoordinates,
+ Angle siteLatitude,
+ Angle siteLongitude) {
+ var domeSettings = profileService.ActiveProfile.DomeSettings;
+
+ // Alt-Az mounts rotate in altitude (around the y-axis) and azimuth (around the z-axis)
+ // Altitude is Dec, Azimuth is Azimuth derived from RA/Dec + LST
+
+ // Convert scope RA/Dec to horizontal coordinates (Alt/Az)
+ var topocentric = scopeCoordinates.Transform(siteLatitude, siteLongitude, 0d); // elevation not critical here
+
+ // Altitude rotation: scope tilts up from horizontal
+ var altitudeRotation = Matrix4x4.CreateRotationY((float)(topocentric.Altitude.Radians));
+
+ // Azimuth rotation: scope rotates around the dome's vertical axis (z-axis)
+ var azimuthRotation = Matrix4x4.CreateRotationZ((float)(-topocentric.Azimuth.Radians));
+
+ // Determine hemisphere direction
+ var latitudeFactor = siteLatitude.Radians >= 0 ? 1.0 : -1.0;
+
+ // Mount offset from dome center
+ var mountOffset = Matrix4x4.CreateTranslation(new Vector3(
+ (float)(domeSettings.ScopePositionNorthSouth_mm * latitudeFactor), // X: North
+ (float)(-domeSettings.ScopePositionEastWest_mm * latitudeFactor), // Y: East
+ (float)domeSettings.ScopePositionUpDown_mm // Z: Up
+ ));
+
+ // Account for any lateral axis and vertical axis offsets to accomodate side-by-side or piggyback telescopes
+ var offsets = Matrix4x4.CreateTranslation(new Vector3(
+ 0.0f,
+ -(float)domeSettings.LateralAxis_mm,
+ (float)domeSettings.GemAxis_mm // Reusing GemAxis_mm for vertical offset in Alt-Az mounts since the basic meaning is the same
+ ));
+
+ return mountOffset * (azimuthRotation * altitudeRotation * offsets);
+ }
}
}
\ No newline at end of file
diff --git a/NINA.Profile/DomeSettings.cs b/NINA.Profile/DomeSettings.cs
index 41a5c0a91..3e0a88822 100644
--- a/NINA.Profile/DomeSettings.cs
+++ b/NINA.Profile/DomeSettings.cs
@@ -30,12 +30,13 @@ public void OnDeserializing(StreamingContext context) {
protected override void SetDefaultValues() {
Id = "No_Device";
- LastDeviceName = "";
+ LastDeviceName = string.Empty;
ScopePositionEastWest_mm = 0.0;
ScopePositionNorthSouth_mm = 0.0;
ScopePositionUpDown_mm = 0.0;
DomeRadius_mm = 0.0;
GemAxis_mm = 0.0;
+ LateralAxis_mm = 0.0;
AzimuthTolerance_degrees = 2.0;
FindHomeBeforePark = false;
DomeSyncTimeoutSeconds = 120;
diff --git a/NINA/View/Options/DomeView.xaml b/NINA/View/Options/DomeView.xaml
index 79c922b07..35ffbd5f2 100644
--- a/NINA/View/Options/DomeView.xaml
+++ b/NINA/View/Options/DomeView.xaml
@@ -152,6 +152,9 @@
+
+
+
@@ -182,6 +185,9 @@
+
+
+
@@ -202,6 +208,39 @@
Text="{Binding DecOffsetHorizontal_mm, UpdateSourceTrigger=LostFocus}"
Unit="mm" />
+
+
+
+
+
+
+
+
+
+
+
n
- N.I.N.A. now queries the ASCOM device name after connecting to the driver.
- **ASCOM Device State**
- For drivers that implement the new ASCOM 7 Device State the application will now use the state when possible instead of polling individual fields
+- **Domes with Alt-Az mounts**
+ - Alt-Az mounts are a new mount configuration that is supported under Options > Dome. This permits one to define mount and OTA offsets that result in proper dome azimuthal rotation for an alt-az mount, or any side-by-side or piggy-backed telescopes mounted on a main telescope.
- ** Dome/Roof safety **
- Optionally disallow the mount to be unparked if the dome or roof controller reports a shutter state other than Open.
- ** Switch Polling**