For successful automated astrophotography, the slot in the observatory dome must be synhronised with the telescope as it tracks the sky and performs slews. In most cases, use of ASCOM will mean that you do not have to worry about the calculation of the dome azimuth - this is all done for you after correct configuration. In some cases you may wish to implment your own code to perform this calculation. The problem is not as simple as it might first appear. One cannot simply set the dome slot azimuth to the pointing azimuth of the telescope. With a GEM mount the correct solution can appear unintuitive.
Take the following example:
Telescope pointing due south at the horizon. Scope on the east side of the pier. Putting the dome slit at
180 is not the correct solution. The scope is hanging out to one side. The required dome azimuth is more
like 160 degrees - depending on various factors.
The "factors" are broadly......
Taking the above case, even with x=y=z=0 the COG-Optical (COGO) will mean the dome azimuth has to be a bit further east than 180. If x=y=z=COGO then the azimuth would be 180. This is now aparently a more complex problem but the solution is straightfoward using the proper mathematics.
Be warned : Some of the solutions I have seen on the internet are horrendously over complicated and try and do the whole thing with trigonometry.
With vectors, the solution is a joy.
In our case, θ is hour angle and φ is latitude - all assuming we are on a polar aligned mount!
For practical programming, the Math.net programming library makes this into a few simple lines of code.
Sample C# code
public DomeAltAz Get(double domeR, double HourAngle, double pierside, double ALT, double AZ)
{
double inc = M_PI / 2 - ALT;
double az = M_PI / 2 - AZ;
//origin of dome, 0,0,0
var c = new DenseVector(new double[] { 0, 0, 0 });
//setup the intersection of RA And DEC axis which is constant.
var cog = new DenseVector(new double[] { offsetEW, offsetNS, offsetUP });
//now work out the cogo point, intersection of optical axis and dec axis, i.e. the bit that moves
var cogtoO = new DenseVector(new double[] {
pierside*r*cos(HourAngle), //x
pierside*-r*sin(latitude)*sin(HourAngle), //y
pierside*r*cos(latitude)*sin(HourAngle) //z
});
var o = cog + cogtoO;
double xm, ym, zm;
//3d cartesian coordinates or unit vector for the actual OTA pointing direction
xm = Math.Sin(inc) * Math.Cos(az);
ym = Math.Sin(inc) * Math.Sin(az);
zm = Math.Cos(inc);
var l = new DenseVector(new double[] { xm, ym, zm });
l = l.Normalize(2);
//do the actual equation
var underRoot = sqr(l.DotProduct(o - c))- sqr((o - c).Norm(2)) + sqr(domeR);
var d = -l.DotProduct(o - c) + Math.Sqrt(underRoot);
var s = c + o + (l * d);
var domealtaz = new DomeAltAz();
domealtaz.DomeAzimuth = M_PI / 2 - Math.Atan2(s[1], s[0]);
if (domealtaz.DomeAzimuth < 0) domealtaz.DomeAzimuth += 2 * M_PI;
domealtaz.DomeAltitude = M_PI / 2 - Math.Acos(s[2] / domeR);
domealtaz.cogtoO = cogtoO;
return domealtaz;
}