Hi all,
here is a DragScript which controls the image acquisition with a 10micron mount from dusk till dawn. Hopefully it will be a useful example for someone. It is not a polished, production ready solution. For example the error handling could be probably improved. But it works well for me.
I do not have a permanent pier or observatory and have to set up the scope at the evening. After that Voyager takes care of everything.
The script synchronizes the mount time with the notebook time using the 10micron Clock Sync utility:
https://www.10micron.eu/forum/viewtopic.php?f=3&t=441
When the sky is dark enough, the script builds a model for the mount using ModelCreator.
See Utilities: https://www.astromi.ch/downloads/
Then it automatically images a number of targets according to their hour angle position, i.e. when the targets are at the highest positions near the meridian. I’ve configured it to start at -3.5HA. Each sequence has the “Exit Sequence if Target is after this HourAngle” checkbox enabled. The EdgeHD scope here does not like meridian flips, so I set the “after this HourAngle” value to -0.1. For a different kind of equipment you can choose other values of course.
The script has a white list of targets to be imaged, so I do not have to remove targets from the script if I do not want to image them anymore. I can just edit the white list. M3 sequence is not active in the script example.
If you have never used ModelCreator before, then you should configure it first and make sure that it can build a model in interactive mode. I use it with an ASCOM camera driver. See the ModelCreator documentation for the meaning of the command line parameters. You will probably have to change the name of the model points file in the DragScript.
The DragScript uses two Python scripts, which are located in C:\Astro\Voyager directory on my notebook.
The first is mcpoll.py, which parses the ModelCreator’s log file in order to get the modelling results. You’ll have to install the latest Python 3.8.2 from https://www.python.org/downloads/ to be able to use it. Verify that the python script works by executing (assuming that the python script is located in C:\Astro\Voyager)
py C:\Astro\Voyager\mcpoll.py
from command prompt window (cmd.exe) and look for the output, which should be “OK”.
The python script assumes that the log is located in default directory:
C:/Users/USERNAME/Documents/Astromi/ModelCreator/Log
You can edit the mcpoll.py script to set a different location of the ModelCreator logs.
The other helper python script is signal.py. It is a custom Signal handler, similar to existing DragScript e-mail and other signals. Currently it simply writes the message to a log file.
I’ve tested the scripts only with English-US Windows 10 64 bit version. So I’m not sure how they will work with other languages.
Best regards,
Vitali
10MicronImaging_Forum_Public.vos (139.5 KB)
Here is the script in text form:
1 - Start: Events At Start are DISABLE
2 - Script
3 - Remark: ================== Automation from Startup to Shutdown: GM1000HPS ======================
4 - Remark: --- Edit the white list of the target names in the 'Run Sequences' block to choose targets
5 - External Script: py.exe C:\Astro\Voyager\signal.py "Script started"
6 - Block: Start Required Applications
7 - Remark: ==========================================================
8 - Remark: --- For example start an application which controls the anti-dew heater
9 - Remark: --- 10Micron ClockSync for 2 minutes
10 - External Script: C:\Program Files (x86)\10micron\ClockSyncW\clocksync_w.exe
11 - Block: Startup 45 min before Astronomical Darkness
12 - Remark: ==========================================================
13 - Remark: --- Put your location here
14 - Wait Astronomical Night: Manual Data [LAT:00° 00' 00" N LON: 00° 00' 00" E] - Offset (Before) 00:45:00 [hh:mm:ss]
15 - Connect Setup
16 - IF OK
17 - Goto Block: Initial Setup
18 - Wait Time: 00:02:00 [hh:mm:ss] Interval
19 - Repeat Block For n Times: 5
20 - Goto Block: Terminate Session
21 - Block: Initial Setup
22 - Remark: ==========================================================
23 - Remark: ---- Stop tracking and wait, then unpark the mount, if it was in parked state
24 - Stop Tracking
25 - Remark: --- Verify: Dew schield. Scope temperature. Focuser position. Clouds. Tighten clutches.
26 - Wait User OK: without timeout
27 - Wait Astronomical Night: Data from connected Setup - Offset (Before) 00:30:00 [hh:mm:ss]
28 - Unparking
29 - Start Tracking
30 - Block: Initial focus
31 - Remark: ==========================================================
32 - Remark: --- Initial autofocus before building the model
33 - Goto ALT/AZ: ALT 80 00 00 - AZ 160 00 00 - FC: False
34 - Start Tracking
35 - Precise Pointing RoboStar Star: Bayer Matrix
36 - IF OK
37 - AutoFocus with RoboStar: Bayer Matrix - AutoFocus OnPlace
38 - IF OK
39 - Goto Block: Build model for the mount
40 - Wait Time: 00:05:00 [hh:mm:ss] Interval
41 - Repeat Block Until Astronomical Night End: Data from connected Setup - Offset (Before) 00:30:00 [hh:mm:ss]
42 - Goto Block: Terminate Session
43 - Block: Build model for the mount
44 - Remark: ==========================================================
45 - Remark: --- Run Model Creator. Use Python script which checks the modelling result
46 - Remark: --- Set the 'disconnectControl' value below to 'disconnect' in order to disconnect equipment before the ModelCreator run
47 - String: disconnectControl - Init Value = ""
48 - DO IF STRING VALUE: disconnectControl Contains "disconnect"
49 - Remark: --- Disconnect equipment to let Model Creator use the camera and the mount. Required if the mount is connected via a COM port
50 - Disconnect Setup
51 - Wait Time: 00:00:30 [hh:mm:ss] Interval
52 - Remark: --- Start ModelCreator without waiting. Python script will periodically read the ModelCreator log file
53 - External Script: C:\Program Files (x86)\ModelCreator 2\ModelCreator.exe --profile GM1000_EHD11_ASI071 --options ClearExisting,IncludeRefinement --modelPoints C:\Users\Vitali\Documents\Astromi\ModelCreator\Points\East_E3HA_W1HA_20-40Dec.csv
54 - Remark: --- Wait a bit before polling
55 - Wait Time: 00:02:00 [hh:mm:ss] Interval
56 - Block: Check modelling result
57 - Remark: --- Poll every 1 minute for 40 minutes
58 - String: result - Init Value = ""
59 - External Script: py.exe C:\Astro\Voyager\mcpoll.py; StringCheck=OK; OutString=result
60 - IF OK
61 - Goto Block: Reconnect equipment
62 - DO IF STRING VALUE: result Contains "Polar align error"
63 - External Script: py.exe C:\Astro\Voyager\signal.py "PA error is too large"
64 - Goto Block: Terminate Session
65 - DO IF STRING VALUE: result Contains "RMS"
66 - External Script: py.exe C:\Astro\Voyager\signal.py "RMS is large, repeating model run"
67 - Goto Block: Repeat modelling run
68 - DO IF STRING VALUE: result Contains "Failed"
69 - External Script: py.exe C:\Astro\Voyager\signal.py "Model run failed"
70 - Goto Block: Repeat modelling run
71 - Wait Time: 00:01:00 [hh:mm:ss] Interval
72 - Repeat Block For n Times: 40
73 - Remark: --- ModelCreator took too long. Hangs? Terminate because it is not known what is happening
74 - External Script: py.exe C:\Astro\Voyager\signal.py "MC timeout"
75 - Goto Block: Terminate Session
76 - Block: Repeat modelling run
77 - Wait Time: 00:01:00 [hh:mm:ss] Interval
78 - Repeat Block For n Times: 3
79 - External Script: py.exe C:\Astro\Voyager\signal.py "Failed to build a model"
80 - Goto Block: Terminate Session
81 - Block: Reconnect equipment
82 - Remark: ==========================================================
83 - Remark: ---- Reconnect equipment after the modelling run or if the script is restarted from here without modelling
84 - Connect Setup
85 - IF OK
86 - Goto Block: Start Sequences
87 - Wait Time: 00:02:00 [hh:mm:ss] Interval
88 - Repeat Block For n Times: 5
89 - External Script: py.exe C:\Astro\Voyager\signal.py "Failed to reconnect equipment after a modelling run"
90 - Goto Block: Terminate Session
91 - Block: Start Sequences
92 - Remark: ==========================================================
93 - Cool Down: -5[°C] - Sync Cooling - Use CCD Firmware Cooldown
94 - Wait Astronomical Night: Data from connected Setup - Offset (Before) 00:10:00 [hh:mm:ss]
95 - Block: Run Sequences
96 - Remark: ==========================================================
97 - Remark: --- White list of targets to image. Followed by each target's sequence block
98 - String: targets - Init Value = "NGC4565 NGC5396 M013"
99 - Block: Sequence NGC4565
100 - DO IF STRING VALUE: targets Contains "NGC4565"
101 - DO IF HA BETWEEN: Between -3.5 and -1 [Hours] - ( RA 12 36 21.000 - DEC 25 59 14.61 )
102 - Start Tracking
103 - External Script: py.exe C:\Astro\Voyager\signal.py Imaging NGC4565
104 - Sequence: Start Immediately - End Astronomical Night - C:\Users\Vitali\Documents\Voyager\ConfigSequence\NGC4565.s2q
105 - Block: Sequence NGC5396
106 - DO IF STRING VALUE: targets Contains "NGC5396"
107 - DO IF HA BETWEEN: Between -3.5 and -1 [Hours] - ( RA 13 56 56.000 - DEC 29 09 51.65 )
108 - Start Tracking
109 - External Script: py.exe C:\Astro\Voyager\signal.py Imaging NGC5396
110 - Sequence: Start Immediately - End Astronomical Night - C:\Users\Vitali\Documents\Voyager\ConfigSequence\NGC5396.s2q
111 - Block: Sequence M3
112 - DO IF STRING VALUE: targets Contains "M003"
113 - DO IF HA BETWEEN: Between -3.5 and -1 [Hours] - ( RA 13 42 11.620 - DEC 28 22 38.20 )
114 - Start Tracking
115 - External Script: py.exe C:\Astro\Voyager\signal.py Imaging M3
116 - Sequence: Start Immediately - End Astronomical Night - C:\Users\Vitali\Documents\Voyager\ConfigSequence\M3.s2q
117 - Block: Sequence M13
118 - DO IF STRING VALUE: targets Contains "M013"
119 - DO IF HA BETWEEN: Between -3.5 and -1 [Hours] - ( RA 16 41 42.000 - DEC 36 27 40.75 )
120 - Start Tracking
121 - External Script: py.exe C:\Astro\Voyager\signal.py Imaging M13
122 - Sequence: Start Immediately - End Astronomical Night - C:\Users\Vitali\Documents\Voyager\ConfigSequence\M13.s2q
123 - Stop Tracking
124 - Wait Time: 00:01:00 [hh:mm:ss] Interval
125 - Repeat Block Until Astronomical Night End: Data from connected Setup - Offset (Before) 00:00:00 [hh:mm:ss]
126 - Block: Terminate Session
127 - Remark: ==========================================================
128 - Remark: ---- Run Good Night Shutdown action
129 - Good Night: Async Warmup - Park - No CCD Filter Select
130 - Disconnect Setup
131 - Disable Events
132 - Goto End
133 - End
134 - Events
mcpoll.py:
# Find the current ModelCreator log
# See if it is completed
from os import listdir
from os.path import isdir, isfile, join
from pathlib import Path
import re
# ModelCreator log directory default location
MCLogDir = join(str(Path.home()), 'Documents/Astromi/ModelCreator/Log')
# You should set the directory explicitely if you have customized the log location in FolderLocation.ini
#MCLogDir = 'C:/Users/Vitali/Documents/Astromi/ModelCreator/Log'
if not isdir(MCLogDir):
print('No log')
quit()
# Read the list of log files. MC naming allows to sort the list to find the latest log
MCLogFiles = [f for f in listdir(MCLogDir) if isfile(join(MCLogDir, f))]
if len(MCLogFiles) <= 0:
print('No log')
quit()
MCLogFiles.sort()
MCLastLog = join(MCLogDir, MCLogFiles[len(MCLogFiles) - 1])
# Read the log lines
l = 0
with open(MCLastLog, 'r') as f:
l = f.read().splitlines()
if len(l) <= 0:
print('No log')
quit()
# Check if the modelling run is completed
# 22:41:06: General - Notice - Modelling run successfully completed
# 16:58:46: General - Notice - Shutting down
fCompleted = False
idxCompleted = -1
for i in range(len(l) - 1, -1, -1):
if 'Modelling run successfully completed' in l[i]:
idxCompleted = i
break
if 'Shutting down' in l[i]:
fCompleted = True
if not fCompleted:
print('Log incomplete')
quit()
if idxCompleted < 1:
print('Failed')
quit()
# TODO Check the log time, it should not be too far in the past
# Check if the model looks ok
# 22:41:06: General - Notice - Modelling statistics
# 22:41:06: General - Info - Model run completed in 0h 20min 15s
# 22:41:06: General - Info - Total Points in modelling run: 35
# 22:41:06: General - Info - Successfully solved points: 30
# 22:41:06: General - Info - Points failed to solve: 5
# 22:41:06: Mount - Notice - Alignment Info:
# 22:41:06: Mount - Notice - Polar align error: 0* 0' 9.7"
# 22:41:06: Mount - Notice - Position Angle: 319* 51' 36.0"
# 22:41:06: Mount - Notice - Orthogonality: 0* 7' 28.1"
# 22:41:06: Mount - Notice - Model-Terms: 09
# 22:41:06: Mount - Notice - RMS: 6.4 "
# 22:41:06: General - Notice - Modelling run successfully completed
def findNumbers(value):
return [float(v) for v in re.findall(r'[+|-]?\d*\.\d+|\d+', value)]
TotalPoints = 0
SolvedPoints = 0
FailedPoints = 0
PolarAlignError = [0.0, 0.0, 0.0] # [degrees, arcminutes, arcseconds]
RMS = 0.0
for i in range(idxCompleted, -1, -1):
if 'Modelling statistics' in l[i]:
break
# What kind of a line is it
parts = l[i].partition('Total Points in modelling run:')
if parts[1] != '':
value = parts[2].strip()
TotalPoints = int(value)
continue
parts = l[i].partition('Successfully solved points:')
if parts[1] != '':
value = parts[2].strip()
SolvedPoints = int(value)
continue
parts = l[i].partition('Points failed to solve:')
if parts[1] != '':
value = parts[2].strip()
FailedPoints = int(value)
continue
parts = l[i].partition('Polar align error:')
if parts[1] != '':
value = parts[2].strip()
PolarAlignError = findNumbers(value) # [degrees, arcminutes, arcseconds]
continue
parts = l[i].partition('RMS:')
if parts[1] != '':
value = parts[2].strip()
valueFloats = findNumbers(value) # [arcseconds]
RMS = valueFloats[0]
continue
#print(TotalPoints, SolvedPoints, FailedPoints, PolarAlignError, RMS)
# PA error greater than 3 arcminutes is not OK
if PolarAlignError[0] > 0 or PolarAlignError[1] > 3.0:
print('Polar align error', PolarAlignError)
quit()
# RMS greater than 15 arcseconds is not OK
if RMS > 15.0:
print('RMS', RMS)
quit()
print('OK')
This is signal.py:
# Runs from drag script and delivers a message
import sys
import datetime
timestamp = '{date:%Y-%m-%d %H:%M:%S}: '.format( date=datetime.datetime.now() )
if len(sys.argv) <= 1:
message = 'nothing'
else:
message = ' '.join(sys.argv[1:])
# TODO A more visible notification.
# Simply write to a log file
with open('C:/Astro/Voyager/signals.txt', 'a') as f:
f.write(timestamp)
f.write(message)
f.write('\n')