From 9f948c606e278832aeb53823473d482a55c046cf Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 14 Feb 2017 16:56:35 +1100 Subject: [PATCH 001/149] * Small debug --- pocs/state/states/default/analyzing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pocs/state/states/default/analyzing.py b/pocs/state/states/default/analyzing.py index 0a1e50d43..0892e60b3 100644 --- a/pocs/state/states/default/analyzing.py +++ b/pocs/state/states/default/analyzing.py @@ -12,6 +12,7 @@ def on_enter(event_data): pocs.observatory.analyze_recent() if pocs.force_reschedule: + pocs.say("Forcing a move to the scheduler") pocs.next_state = 'scheduling' # Check for minimum number of exposures From d189ba5fa3d2bb68fede1aab03db898c27519b2d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 28 Mar 2017 14:35:48 -1000 Subject: [PATCH 002/149] Cahnges from updates --- pocs/mount/ioptron.py | 3 ++- pocs/mount/serial.py | 7 ++++++- pocs/utils/messaging.py | 7 ++++++- resources/mounts/ioptron.yaml | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pocs/mount/ioptron.py b/pocs/mount/ioptron.py index ef5f2d128..cab774ae6 100644 --- a/pocs/mount/ioptron.py +++ b/pocs/mount/ioptron.py @@ -149,7 +149,8 @@ def initialize(self, set_rates=True, unpark=False, *arg, **kwargs): actual_mount_info = self.query('mount_info') expected_version = self.commands.get('version').get('response') - expected_mount_info = "{:04d}".format(self.config['mount'].get('model', 30)) + expected_mount_info = self.commands.get('mount_info').get('response') + # expected_mount_info = "{:04d}".format(self.config['mount'].get('model', 30)) self._is_initialized = False # Test our init procedure for iOptron diff --git a/pocs/mount/serial.py b/pocs/mount/serial.py index 17d45a3f0..f23d47951 100644 --- a/pocs/mount/serial.py +++ b/pocs/mount/serial.py @@ -211,8 +211,13 @@ def _get_command(self, cmd, params=None): raise error.InvalidMountCommand( '{} expects params: {}'.format(cmd, cmd_info.get('params'))) + try: + params = params[0] + except Exception: + pass + full_command = "{}{}{}{}".format( - self._pre_cmd, cmd_info.get('cmd'), params[0], self._post_cmd) + self._pre_cmd, cmd_info.get('cmd'), params, self._post_cmd) else: full_command = "{}{}{}".format( self._pre_cmd, cmd_info.get('cmd'), self._post_cmd) diff --git a/pocs/utils/messaging.py b/pocs/utils/messaging.py index dc4ea79a9..0a1d7b90e 100644 --- a/pocs/utils/messaging.py +++ b/pocs/utils/messaging.py @@ -2,6 +2,8 @@ import logging import zmq +import yaml + from astropy import units as u from astropy.time import Time from bson import ObjectId @@ -138,7 +140,10 @@ def receive_message(self, flags=0): pass else: msg_type, msg = message.split(' ', maxsplit=1) - msg_obj = loads(msg) + try: + msg_obj = loads(msg) + except Exception: + msg_obj = yaml.load(msg) return msg_type, msg_obj diff --git a/resources/mounts/ioptron.yaml b/resources/mounts/ioptron.yaml index 910234cd7..bee49f79d 100644 --- a/resources/mounts/ioptron.yaml +++ b/resources/mounts/ioptron.yaml @@ -158,4 +158,4 @@ version: response: 'V1.00' mount_info: cmd: MountInfo - response: '0030' + response: '8407' From 192ad19a7d96ce6853fdf21280c9d5273f71092a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 11:27:15 -1000 Subject: [PATCH 003/149] * Fixing regression with mount that was causing date/time and location to not be set properly (fixes parking for PAN001 on MLO) * Adding gmt_offset as location property until better consolidation is done (with timezone and utc_offset) --- conf_files/pocs.yaml | 1 + pocs/mount/serial.py | 5 ----- resources/mounts/ioptron.yaml | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/conf_files/pocs.yaml b/conf_files/pocs.yaml index 8e2f3206e..d246316bc 100644 --- a/conf_files/pocs.yaml +++ b/conf_files/pocs.yaml @@ -9,6 +9,7 @@ location: horizon: 30 # Degrees twilight_horizon: -18 # Degrees timezone: US/Hawaii + gmt_offset: -600 directories: base: /var/panoptes images: images diff --git a/pocs/mount/serial.py b/pocs/mount/serial.py index f23d47951..f9c11f003 100644 --- a/pocs/mount/serial.py +++ b/pocs/mount/serial.py @@ -211,11 +211,6 @@ def _get_command(self, cmd, params=None): raise error.InvalidMountCommand( '{} expects params: {}'.format(cmd, cmd_info.get('params'))) - try: - params = params[0] - except Exception: - pass - full_command = "{}{}{}{}".format( self._pre_cmd, cmd_info.get('cmd'), params, self._post_cmd) else: diff --git a/resources/mounts/ioptron.yaml b/resources/mounts/ioptron.yaml index bee49f79d..910234cd7 100644 --- a/resources/mounts/ioptron.yaml +++ b/resources/mounts/ioptron.yaml @@ -158,4 +158,4 @@ version: response: 'V1.00' mount_info: cmd: MountInfo - response: '8407' + response: '0030' From c0dc5f19a0ab52e78b9842e6f8c7cdc39acccb44 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 22:13:05 -1000 Subject: [PATCH 004/149] * Serial line is a process-safe `Queue` --- pocs/utils/rs232.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 8536d0a17..3896c0816 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -1,7 +1,9 @@ -import multiprocessing import serial as serial import time +from multiprocessing import Process +from multiprocessing import Queue + from .. import PanBase from .error import BadSerialConnection @@ -30,11 +32,11 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.ser.interCharTimeout = None self.name = name - self.serial_receiving = '' + self.serial_receiving = Queue() if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") - self.process = multiprocessing.Process(target=self.receiving_function) + self.process = Process(target=self.receiving_function) self.process.daemon = True self.process.name = "PANOPTES_{}".format(name) @@ -93,7 +95,7 @@ def receiving_function(self): buffer = buffer + self.read() if '\n' in buffer: lines = buffer.split('\n') # Guaranteed to have at least 2 entries - self.serial_receiving = lines[-2] + self.serial_receiving.put_nowait(lines[-2]) # If the Arduino sends lots of empty lines, you'll lose the # last filled line, so you could make the above statement conditional # like so: if lines[-2]: serial_receiving = lines[-2] @@ -144,7 +146,7 @@ def get_reading(self): if not self.ser: return 0 for i in range(40): - raw_line = self.serial_receiving + raw_line = self.serial_receiving.get_nowait() try: return raw_line.strip() except ValueError: From c522fe4b966883315e6c3817786fc7079bf9ebaa Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 22:22:10 -1000 Subject: [PATCH 005/149] * don't use a threaded serial connection for mount --- pocs/mount/serial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/mount/serial.py b/pocs/mount/serial.py index f9c11f003..63c23fad1 100644 --- a/pocs/mount/serial.py +++ b/pocs/mount/serial.py @@ -21,7 +21,7 @@ def __init__(self, *args, **kwargs): self.logger.error('No mount port specified, cannot create mount\n {}'.format(self.config['mount'])) try: - self.serial = rs232.SerialData(port=self._port) + self.serial = rs232.SerialData(port=self._port, threaded=False) except Exception as err: self.serial = None raise error.MountNotFound(err) From 1566bff01c3bc870685d8d1cb550f8ad7fc1e080 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 22:58:56 -1000 Subject: [PATCH 006/149] * Use `deque` instead of `Queue` --- pocs/utils/rs232.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 3896c0816..1a196519e 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -1,8 +1,8 @@ import serial as serial import time +from collections import deque from multiprocessing import Process -from multiprocessing import Queue from .. import PanBase from .error import BadSerialConnection @@ -32,7 +32,7 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.ser.interCharTimeout = None self.name = name - self.serial_receiving = Queue() + self.serial_receiving = deque(None, 100) if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") @@ -95,7 +95,7 @@ def receiving_function(self): buffer = buffer + self.read() if '\n' in buffer: lines = buffer.split('\n') # Guaranteed to have at least 2 entries - self.serial_receiving.put_nowait(lines[-2]) + self.serial_receiving.appendleft(lines[-2]) # If the Arduino sends lots of empty lines, you'll lose the # last filled line, so you could make the above statement conditional # like so: if lines[-2]: serial_receiving = lines[-2] @@ -143,15 +143,22 @@ def read(self): return response_string def get_reading(self): + raw_line = 0. if not self.ser: return 0 + for i in range(40): - raw_line = self.serial_receiving.get_nowait() try: - return raw_line.strip() + raw_line = self.serial_receiving.pop().strip() + break + except IndexError: + time.sleep(.005) + continue except ValueError: time.sleep(.005) - return 0. + continue + + return raw_line def clear_buffer(self): """ Clear Response Buffer """ From 5dc4981d8d94de26ae5efa07774c1cabc8bc16d3 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 23:02:20 -1000 Subject: [PATCH 007/149] * Init the deque properly --- pocs/utils/rs232.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 1a196519e..ad38f517a 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -32,7 +32,7 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.ser.interCharTimeout = None self.name = name - self.serial_receiving = deque(None, 100) + self.serial_receiving = deque([], 100) if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") From 917f641da393dbb505af7452c30e6c3de0da9229 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 23:08:57 -1000 Subject: [PATCH 008/149] * Pass queue * Multi-threaded connects after spawn --- pocs/utils/rs232.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index ad38f517a..5fe13a197 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -32,11 +32,11 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.ser.interCharTimeout = None self.name = name - self.serial_receiving = deque([], 100) + self.queue = deque([], 100) if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") - self.process = Process(target=self.receiving_function) + self.process = Process(target=self.receiving_function, args=(self.queue,)) self.process.daemon = True self.process.name = "PANOPTES_{}".format(name) @@ -88,17 +88,18 @@ def disconnect(self): self.ser.close() return not self.is_connected - def receiving_function(self): + def receiving_function(self, queue): + self.connect() buffer = '' while True: try: buffer = buffer + self.read() if '\n' in buffer: lines = buffer.split('\n') # Guaranteed to have at least 2 entries - self.serial_receiving.appendleft(lines[-2]) + queue.appendleft(lines[-2]) # If the Arduino sends lots of empty lines, you'll lose the # last filled line, so you could make the above statement conditional - # like so: if lines[-2]: serial_receiving = lines[-2] + # like so: if lines[-2]: queue = lines[-2] buffer = lines[-1] except IOError as err: print("Device is not sending messages. IOError: {}".format(err)) @@ -149,7 +150,7 @@ def get_reading(self): for i in range(40): try: - raw_line = self.serial_receiving.pop().strip() + raw_line = self.queue.pop().strip() break except IndexError: time.sleep(.005) From b680f6f144a89eeb21bb7a2f69e7437efa7d7858 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 29 Mar 2017 23:13:43 -1000 Subject: [PATCH 009/149] Output to logger --- pocs/utils/rs232.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 5fe13a197..bc81427ef 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -102,13 +102,13 @@ def receiving_function(self, queue): # like so: if lines[-2]: queue = lines[-2] buffer = lines[-1] except IOError as err: - print("Device is not sending messages. IOError: {}".format(err)) + self.logger.warning("Device is not sending messages. IOError: {}".format(err)) time.sleep(2) except UnicodeDecodeError: - print("Unicode problem") + self.logger.warning("Unicode problem") time.sleep(2) except Exception: - print("Uknown problem") + self.logger.warning("Uknown problem") def write(self, value): """ From daf1bb435e8da914c0288faaab94106c360e3491 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 08:27:42 -1000 Subject: [PATCH 010/149] Better deque for serial lines --- pocs/utils/rs232.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index bc81427ef..35e130e81 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -36,7 +36,7 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") - self.process = Process(target=self.receiving_function, args=(self.queue,)) + self.process = Process(target=self.receiving_function) self.process.daemon = True self.process.name = "PANOPTES_{}".format(name) @@ -88,7 +88,7 @@ def disconnect(self): self.ser.close() return not self.is_connected - def receiving_function(self, queue): + def receiving_function(self): self.connect() buffer = '' while True: @@ -96,7 +96,7 @@ def receiving_function(self, queue): buffer = buffer + self.read() if '\n' in buffer: lines = buffer.split('\n') # Guaranteed to have at least 2 entries - queue.appendleft(lines[-2]) + self.queue.append(lines[-2]) # If the Arduino sends lots of empty lines, you'll lose the # last filled line, so you could make the above statement conditional # like so: if lines[-2]: queue = lines[-2] @@ -150,7 +150,7 @@ def get_reading(self): for i in range(40): try: - raw_line = self.queue.pop().strip() + raw_line = self.queue.popleft().strip() break except IndexError: time.sleep(.005) From af2f41ea71a1f6fceca9546b6ced4893f2e3ce27 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 08:47:37 -1000 Subject: [PATCH 011/149] Better serial deque --- pocs/utils/rs232.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 35e130e81..338433b49 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -2,7 +2,7 @@ import time from collections import deque -from multiprocessing import Process +from threading import Thread from .. import PanBase from .error import BadSerialConnection @@ -33,10 +33,11 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.name = name self.queue = deque([], 100) + self._is_listening = False if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") - self.process = Process(target=self.receiving_function) + self.process = Thread(target=self.receiving_function, args=(self.queue,)) self.process.daemon = True self.process.name = "PANOPTES_{}".format(name) @@ -58,9 +59,14 @@ def is_connected(self): return connected + @property + def is_listening(self): + return self._is_listening + def start(self): """ Starts the separate process """ self.logger.debug("Starting serial process: {}".format(self.process.name)) + self._is_listening = True self.process.start() def connect(self): @@ -88,19 +94,13 @@ def disconnect(self): self.ser.close() return not self.is_connected - def receiving_function(self): + def receiving_function(self, q): self.connect() - buffer = '' - while True: + while self.is_listening: try: - buffer = buffer + self.read() - if '\n' in buffer: - lines = buffer.split('\n') # Guaranteed to have at least 2 entries - self.queue.append(lines[-2]) - # If the Arduino sends lots of empty lines, you'll lose the - # last filled line, so you could make the above statement conditional - # like so: if lines[-2]: queue = lines[-2] - buffer = lines[-1] + line = self.read() + self.queue.append(line) + q.append(line) except IOError as err: self.logger.warning("Device is not sending messages. IOError: {}".format(err)) time.sleep(2) From ef2538c235caca18de262c3be364f7abd6cd913b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 09:13:39 -1000 Subject: [PATCH 012/149] Serial line * Loop delay is a param * Easy way to stop --- pocs/utils/rs232.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 338433b49..b972824dd 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -34,6 +34,7 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.name = name self.queue = deque([], 100) self._is_listening = False + self.loop_delay = 2. if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") @@ -69,6 +70,12 @@ def start(self): self._is_listening = True self.process.start() + def stop(self): + """ Starts the separate process """ + self.logger.debug("Stopping serial process: {}".format(self.process.name)) + self._is_listening = False + self.process.join() + def connect(self): """ Actually set up the Thread and connect to serial """ @@ -100,7 +107,6 @@ def receiving_function(self, q): try: line = self.read() self.queue.append(line) - q.append(line) except IOError as err: self.logger.warning("Device is not sending messages. IOError: {}".format(err)) time.sleep(2) @@ -108,7 +114,9 @@ def receiving_function(self, q): self.logger.warning("Unicode problem") time.sleep(2) except Exception: - self.logger.warning("Uknown problem") + self.logger.warning("Unknown problem") + + time.sleep(self.loop_delay) def write(self, value): """ From 371f1f1f5acde05e8d90ffa95d866803f8de2e12 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 09:17:22 -1000 Subject: [PATCH 013/149] * Serial get_reading just returns item from queue --- pocs/utils/rs232.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index b972824dd..9fca1938f 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -152,20 +152,15 @@ def read(self): return response_string def get_reading(self): - raw_line = 0. - if not self.ser: - return 0 + """ Get reading from the queue - for i in range(40): - try: - raw_line = self.queue.popleft().strip() - break - except IndexError: - time.sleep(.005) - continue - except ValueError: - time.sleep(.005) - continue + Returns: + str: Item in queue + """ + try: + raw_line = self.queue.popleft().strip() + except Exception: + raw_line = None return raw_line From 91fd2c6bbeb6d22421c3e1c0cf740b615490edf2 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 09:34:24 -1000 Subject: [PATCH 014/149] Serial reader * Adding a timestamp to queue --- pocs/utils/rs232.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 9fca1938f..f9cf1f3f9 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -106,7 +106,8 @@ def receiving_function(self, q): while self.is_listening: try: line = self.read() - self.queue.append(line) + ts = time.strftime('%Y-%m-%dT%H:%M:%S %Z', time.gmtime()) + self.queue.append((ts, line)) except IOError as err: self.logger.warning("Device is not sending messages. IOError: {}".format(err)) time.sleep(2) From 73aa4698139e0b07d5f2cd4320ef3f8fc7f99197 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 09:45:34 -1000 Subject: [PATCH 015/149] Return none if None otherwise tuple --- pocs/utils/rs232.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index f9cf1f3f9..dbc16fdbe 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -158,12 +158,14 @@ def get_reading(self): Returns: str: Item in queue """ + info = None try: - raw_line = self.queue.popleft().strip() + ts, data = self.queue.popleft() + info = (ts, data) except Exception: - raw_line = None + pass - return raw_line + return info def clear_buffer(self): """ Clear Response Buffer """ From c7d739328551b93b33db0b386d93786c0d663371 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 19:57:44 -1000 Subject: [PATCH 016/149] * Fix simulator checks --- pocs/core.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pocs/core.py b/pocs/core.py index c740ce81e..fd447057e 100644 --- a/pocs/core.py +++ b/pocs/core.py @@ -280,10 +280,10 @@ def is_dark(self): bool: Is night at location """ - if 'night' in self.config['simulator']: - self.logger.debug("Night simulator says safe") + try: + is_dark = self.config['simulator']['night'] is_dark = True - else: + except KeyError: is_dark = self.observatory.is_dark self.logger.debug("Dark Check: {}".format(is_dark)) @@ -305,10 +305,10 @@ def is_weather_safe(self, stale=180): is_safe = False record = {'safe': False} - if 'weather' in self.config['simulator']: + try: + is_safe = self.config['simulator']['weather'] self.logger.debug("Weather simulator always safe") - is_safe = True - else: + except KeyError: try: record = self.db.current.find_one({'type': 'weather'}) From cadb64a5181c2dac289d5a51b8266b20e96929f8 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 20:09:16 -1000 Subject: [PATCH 017/149] Quick fix --- pocs/core.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pocs/core.py b/pocs/core.py index fd447057e..28b1c7820 100644 --- a/pocs/core.py +++ b/pocs/core.py @@ -281,8 +281,7 @@ def is_dark(self): """ try: - is_dark = self.config['simulator']['night'] - is_dark = True + is_dark = 'night' in self.config['simulator'] except KeyError: is_dark = self.observatory.is_dark @@ -306,7 +305,7 @@ def is_weather_safe(self, stale=180): record = {'safe': False} try: - is_safe = self.config['simulator']['weather'] + is_safe = 'weather' in self.config['simulator'] self.logger.debug("Weather simulator always safe") except KeyError: try: From 5f456e067d2ded2343d8de30e65cb69fe3114888 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 20:13:51 -1000 Subject: [PATCH 018/149] Fix for check --- pocs/core.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/pocs/core.py b/pocs/core.py index 28b1c7820..738ac25fd 100644 --- a/pocs/core.py +++ b/pocs/core.py @@ -284,6 +284,8 @@ def is_dark(self): is_dark = 'night' in self.config['simulator'] except KeyError: is_dark = self.observatory.is_dark + else: + is_dark = self.observatory.is_dark self.logger.debug("Dark Check: {}".format(is_dark)) return is_dark @@ -308,22 +310,24 @@ def is_weather_safe(self, stale=180): is_safe = 'weather' in self.config['simulator'] self.logger.debug("Weather simulator always safe") except KeyError: - try: - record = self.db.current.find_one({'type': 'weather'}) + pass - is_safe = record['data'].get('safe', False) - timestamp = record['date'] - age = (current_time().datetime - timestamp).total_seconds() + try: + record = self.db.current.find_one({'type': 'weather'}) - self.logger.debug("Weather Safety: {} [{:.0f} sec old - {}]".format(is_safe, age, timestamp)) + is_safe = record['data'].get('safe', False) + timestamp = record['date'] + age = (current_time().datetime - timestamp).total_seconds() - except TypeError as e: - self.logger.warning("No record found in Mongo DB") - self.logger.debug('DB: {}'.format(self.db.current)) - else: - if age > stale: - self.logger.warning("Weather record looks stale, marking unsafe.") - is_safe = False + self.logger.debug("Weather Safety: {} [{:.0f} sec old - {}]".format(is_safe, age, timestamp)) + + except TypeError as e: + self.logger.warning("No record found in Mongo DB") + self.logger.debug('DB: {}'.format(self.db.current)) + else: + if age > stale: + self.logger.warning("Weather record looks stale, marking unsafe.") + is_safe = False self._is_safe = is_safe From 61a0fd9546066c65b01caed795992e69aee124da Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 30 Mar 2017 20:43:38 -1000 Subject: [PATCH 019/149] Fixing publisher --- bin/pocs_shell | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index cb46118d7..a4a57ffb8 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -65,13 +65,13 @@ class PocsShell(Cmd): print_info("Starting messaging") # Send commands to POCS via this publisher - self.cmd_publisher = PanMessaging('publisher', self.cmd_pub_port) + self.cmd_publisher = PanMessaging.create_publisher(self.cmd_pub_port) # Receive messages from POCS via this subscriber - self.msg_subscriber = PanMessaging('subscriber', self.msg_sub_port) + self.msg_subscriber = PanMessaging.create_subscriber(self.msg_sub_port) # Send messages to PAWS - self.msg_publisher = PanMessaging('publisher', self.msg_pub_port) + self.msg_publisher = PanMessaging.create_publisher(self.msg_pub_port) def do_setup_pocs(self, *arg): """ Setup and initialize a POCS instance """ From e6a7343aa6d72104bf16c5018e7f7e9cd1a0e54c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 21:40:37 -1000 Subject: [PATCH 020/149] * Adjustment to pole test to use both cameras --- bin/pocs_shell | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index a4a57ffb8..b21a95793 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -285,21 +285,25 @@ class DriftShell(Cmd): print_info('At home position, taking {}x {}sec exposures'.format(num_pics, exp_time)) for i in range(num_pics): - if not self.ready: - break - - try: - fn = '{}/{}_pole_{:02d}.cr2'.format(self.base_dir, start_time, i) - cam0.take_exposure(seconds=exp_time, filename=fn) - print_info('\t{} of {}'.format(i, num_pics)) - + procs = dict() + for cam_name, cam in self.pocs.observatory.cameras.items(): + if not self.ready: + break + + try: + fn = '{}/{}_pole_{}_{:02d}.cr2'.format(self.base_dir, start_time, cam_name.lower(), i) + proc = cam0.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + print_info('\t{} of {}'.format(i, num_pics)) + except KeyboardInterrupt: + print_warning('Pole test interrupted') + break time.sleep(exp_time) - time.sleep(8) # Readout time + + for fn, proc in procs.items(): + proc.join() img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) img_utils.cr2_to_fits(fn, remove_cr2=True) - except KeyboardInterrupt: - print_warning('Pole test interrupted') - break def do_unpark(self, *arg): try: From 75ad27d57b2a0f181b1ecfcd33465d5bae3153c0 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 21:50:03 -1000 Subject: [PATCH 021/149] * Wait for subprocess properly --- bin/pocs_shell | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index b21a95793..e7374e114 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -3,6 +3,8 @@ import os import readline import time +from subprocess import TimeoutExpired + from cmd import Cmd from astropy import units as u @@ -285,23 +287,26 @@ class DriftShell(Cmd): print_info('At home position, taking {}x {}sec exposures'.format(num_pics, exp_time)) for i in range(num_pics): + print_info('\t{} of {}'.format(i, num_pics)) procs = dict() for cam_name, cam in self.pocs.observatory.cameras.items(): if not self.ready: break + fn = '{}/{}_pole_{}_{:02d}.cr2'.format(self.base_dir, start_time, cam_name.lower(), i) + proc = cam0.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + + for fn, proc in procs.items(): try: - fn = '{}/{}_pole_{}_{:02d}.cr2'.format(self.base_dir, start_time, cam_name.lower(), i) - proc = cam0.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - print_info('\t{} of {}'.format(i, num_pics)) + outs, errs = proc.communicate(timeout=exp_time + 15) except KeyboardInterrupt: print_warning('Pole test interrupted') break - time.sleep(exp_time) - - for fn, proc in procs.items(): - proc.join() + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + proc.wait() img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) img_utils.cr2_to_fits(fn, remove_cr2=True) From 2d63328699b521fd7d2922d65017b95a22a4c4a3 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 21:57:22 -1000 Subject: [PATCH 022/149] * Warn for no file --- pocs/utils/images.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index fb840fe26..62afbf890 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -495,6 +495,8 @@ def cr2_to_fits( """ verbose = kwargs.get('verbose', False) + assert os.path.exists(cr2_fname),\ + warn("File doesn't exist, can't make pretty: {}".format(cr2_fname)) if fits_fname is None: fits_fname = cr2_fname.replace('.cr2', '.fits') From 1839171b2754a5f436763fb525dadf98a543cbba Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:01:42 -1000 Subject: [PATCH 023/149] * Wait for process. * Catch process error --- bin/pocs_shell | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index e7374e114..32fc1c57f 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -299,15 +299,20 @@ class DriftShell(Cmd): for fn, proc in procs.items(): try: - outs, errs = proc.communicate(timeout=exp_time + 15) + outs, errs = proc.communicate(timeout=(exp_time + 15)) except KeyboardInterrupt: print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() break except TimeoutExpired: proc.kill() outs, errs = proc.communicate() - proc.wait() - img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + break + try: + img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) img_utils.cr2_to_fits(fn, remove_cr2=True) def do_unpark(self, *arg): From 5d1b1c5f54e0468925019533613532d5c2a923db Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:03:17 -1000 Subject: [PATCH 024/149] * Change log message --- pocs/utils/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index 62afbf890..c83a5019e 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -496,7 +496,7 @@ def cr2_to_fits( verbose = kwargs.get('verbose', False) assert os.path.exists(cr2_fname),\ - warn("File doesn't exist, can't make pretty: {}".format(cr2_fname)) + warn("File doesn't exist, can't convert cr2 to fits: {}".format(cr2_fname)) if fits_fname is None: fits_fname = cr2_fname.replace('.cr2', '.fits') From 10e35e31daffcfec1d7fdd64123b2f12df1ad61d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:05:42 -1000 Subject: [PATCH 025/149] * Convert image exception --- bin/pocs_shell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 32fc1c57f..a68205252 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -311,9 +311,9 @@ class DriftShell(Cmd): break try: img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) except AssertionError: print_warning("Can't make image for {}".format(fn)) - img_utils.cr2_to_fits(fn, remove_cr2=True) def do_unpark(self, *arg): try: From 0ba982d2ad4150e087bc714f2eaeffcd2b5f2496 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:06:12 -1000 Subject: [PATCH 026/149] * Sleep a little before getting image --- bin/pocs_shell | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index a68205252..bc30d74fc 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -309,6 +309,8 @@ class DriftShell(Cmd): proc.kill() outs, errs = proc.communicate() break + + time.sleep(2) try: img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) img_utils.cr2_to_fits(fn, remove_cr2=True) From eecae5c3c4ccab03214c81c94e95445456c8f474 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:15:19 -1000 Subject: [PATCH 027/149] Actually use separate cameras --- bin/pocs_shell | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index bc30d74fc..31653671e 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -278,8 +278,6 @@ class DriftShell(Cmd): num_pics = 5 exp_time = 15 - cam0 = self.pocs.observatory.primary_camera - print_info('Performing pole test, slewing to home') self.do_go_home() while not self.pocs.observatory.mount.is_home: @@ -294,7 +292,7 @@ class DriftShell(Cmd): break fn = '{}/{}_pole_{}_{:02d}.cr2'.format(self.base_dir, start_time, cam_name.lower(), i) - proc = cam0.take_exposure(seconds=exp_time, filename=fn) + proc = cam.take_exposure(seconds=exp_time, filename=fn) procs[fn] = proc for fn, proc in procs.items(): From 4a4a4c34d319ecb712e8034dde3e3df437cc05de Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 22:49:21 -1000 Subject: [PATCH 028/149] Adding rotation images to script --- bin/pocs_shell | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index 31653671e..224588e42 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -315,6 +315,45 @@ class DriftShell(Cmd): except AssertionError: print_warning("Can't make image for {}".format(fn)) + print_info("Doing rotation test") + exp_time = 25 + self.pocs.observatory.mount.query('park') # Manual park position + self.pocs.observatory.mount.unpark() + + # Start exposing on cameras + for direction in ['east', 'west']: + print_info("Rotating to {}".format(direction)) + procs = dict() + for cam_name, cam in self.pocs.observatory.cameras.items(): + fn = '{}/{}_pole_rotation_{}_{}_{:02d}.cr2'.format(self.base_dir, + start_time, direction, cam_name.lower(), i) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + + # Move mount + self.pocs.observatory.mount.move_direction(direction='east', seconds=21) + + # Get exposures + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except KeyboardInterrupt: + print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + def do_unpark(self, *arg): try: self.pocs.observatory.mount.unpark() From d5b110e38cd26d7b4e7f641cbe556711bb1bd68e Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 31 Mar 2017 23:32:11 -1000 Subject: [PATCH 029/149] * Rotation test fixes --- bin/pocs_shell | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 224588e42..ab2e746ec 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -195,6 +195,7 @@ class DriftShell(Cmd): """ Setup and initialize a POCS instance """ args, kwargs = parse_options(*arg) simulator = kwargs.get('simulator', []) + print_info("Simulator: {}".format(simulator)) try: self.pocs = POCS(simulator=simulator) @@ -298,6 +299,8 @@ class DriftShell(Cmd): for fn, proc in procs.items(): try: outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue except KeyboardInterrupt: print_warning('Pole test interrupted') proc.kill() @@ -317,26 +320,27 @@ class DriftShell(Cmd): print_info("Doing rotation test") exp_time = 25 - self.pocs.observatory.mount.query('park') # Manual park position - self.pocs.observatory.mount.unpark() + self.pocs.observatory.mount.move_direction(direction='west', seconds=11) # Start exposing on cameras for direction in ['east', 'west']: print_info("Rotating to {}".format(direction)) procs = dict() for cam_name, cam in self.pocs.observatory.cameras.items(): - fn = '{}/{}_pole_rotation_{}_{}_{:02d}.cr2'.format(self.base_dir, - start_time, direction, cam_name.lower(), i) + fn = '{}/{}_pole_rotation_{}_{}.cr2'.format(self.base_dir, + start_time, direction, cam_name.lower()) proc = cam.take_exposure(seconds=exp_time, filename=fn) procs[fn] = proc # Move mount - self.pocs.observatory.mount.move_direction(direction='east', seconds=21) + self.pocs.observatory.mount.move_direction(direction=direction, seconds=21) # Get exposures for fn, proc in procs.items(): try: outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue except KeyboardInterrupt: print_warning('Pole test interrupted') proc.kill() @@ -349,11 +353,17 @@ class DriftShell(Cmd): time.sleep(2) try: - img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + img_utils.make_pretty_image( + fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) img_utils.cr2_to_fits(fn, remove_cr2=True) except AssertionError: print_warning("Can't make image for {}".format(fn)) + print_info("Done with tests, heading back home") + self.do_go_home() + while not self.pocs.observatory.mount.is_home: + time.sleep(2) + def do_unpark(self, *arg): try: self.pocs.observatory.mount.unpark() From d884ce9a7c1ba66cb2dadf4b792b9f1e1987ec93 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 5 Apr 2017 16:51:03 +1000 Subject: [PATCH 030/149] * Set guide rates properly for new firmware --- pocs/mount/ioptron.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/mount/ioptron.py b/pocs/mount/ioptron.py index cab774ae6..16a28aea8 100644 --- a/pocs/mount/ioptron.py +++ b/pocs/mount/ioptron.py @@ -211,8 +211,8 @@ def _set_initial_rates(self): self.logger.debug('Setting manual moving rate to max') self.query('set_button_moving_rate', 9) self.logger.debug("Mount guide rate: {}".format(self.query('get_guide_rate'))) - self.query('set_guide_rate', '090') - self.guide_rate = float(self.query('get_guide_rate')) / 100.0 + self.query('set_guide_rate', '9090') + self.guide_rate = self.query('get_guide_rate') self.logger.debug("Mount guide rate: {}".format(self.guide_rate)) def _setup_location_for_mount(self): From d6201aecd064df1064befe45a943eb5b375d0ce7 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 09:25:50 +1000 Subject: [PATCH 031/149] * Skip solved files by also checking for existing WCS --- pocs/utils/images.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index c83a5019e..b65aad6fb 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -14,6 +14,7 @@ from astropy import units as u from astropy.io import fits +from astropy.wcs import WCS from pocs.utils import current_time from pocs.utils import error @@ -112,7 +113,8 @@ def get_solve_field(fname, replace=True, remove_extras=True, **kwargs): errs = None # Check for solved file - if kwargs.get('skip_solved', True) and os.path.exists(fname.replace('.fits', '.solved')): + if kwargs.get('skip_solved', True) and \ + (os.path.exists(fname.replace('.fits', '.solved')) or WCS(fname).is_celestial): if verbose: print("Solved file exists, skipping (pass skip_solved=False to solve again): {}".format(fname)) From 773ae294c803a5e70b95be62a248bcc1fe5187ce Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 09:28:02 +1000 Subject: [PATCH 032/149] * Removing the `no-fits2fits` option again (Need a much better solution to this) --- pocs/utils/images.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index b65aad6fb..a2769e8a4 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -51,7 +51,6 @@ def solve_field(fname, timeout=15, solve_opts=[], **kwargs): '--cpulimit', str(timeout), '--no-verify', '--no-plots', - '--no-fits2fits', '--crpix-center', '--match', 'none', '--corr', 'none', From 33ce71672b7f10f5afbce579a2afe4165dc6db03 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 10:18:57 +1000 Subject: [PATCH 033/149] * Fixing up some of the simulator checks --- pocs/core.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pocs/core.py b/pocs/core.py index 738ac25fd..38ec5f110 100644 --- a/pocs/core.py +++ b/pocs/core.py @@ -280,12 +280,15 @@ def is_dark(self): bool: Is night at location """ + # See if dark + is_dark = self.observatory.is_dark + + # Check simulator try: - is_dark = 'night' in self.config['simulator'] + if 'night' in self.config['simulator']: + is_dark = True except KeyError: - is_dark = self.observatory.is_dark - else: - is_dark = self.observatory.is_dark + pass self.logger.debug("Dark Check: {}".format(is_dark)) return is_dark @@ -307,8 +310,10 @@ def is_weather_safe(self, stale=180): record = {'safe': False} try: - is_safe = 'weather' in self.config['simulator'] - self.logger.debug("Weather simulator always safe") + if 'weather' in self.config['simulator']: + is_safe = True + self.logger.debug("Weather simulator always safe") + return is_safe except KeyError: pass From 8646ed83bce9192a7c535ff00ba69de5f82e32b7 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 10:50:45 +1000 Subject: [PATCH 034/149] * Adding specific check for TRAVIS environment variable in solver * NOTE: I hate this --- pocs/utils/images.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index a2769e8a4..2e831b5dd 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -57,6 +57,10 @@ def solve_field(fname, timeout=15, solve_opts=[], **kwargs): '--wcs', 'none', '--downsample', '4', ] + + if 'TRAVIS' in os.environ: + options.append('--no-fits2ifts') + if kwargs.get('clobber', True): options.append('--overwrite') if kwargs.get('skip_solved', True): From 381a216839997bb3d1d91cd14b91c5bd0c8905b3 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 11:09:44 +1000 Subject: [PATCH 035/149] * Fix spelling mistake on FITS option --- pocs/utils/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index 2e831b5dd..6f9aca90c 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -59,7 +59,7 @@ def solve_field(fname, timeout=15, solve_opts=[], **kwargs): ] if 'TRAVIS' in os.environ: - options.append('--no-fits2ifts') + options.append('--no-fits2fits') if kwargs.get('clobber', True): options.append('--overwrite') From 9463b378718b31e9b3eed16813cbc082eba76712 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 14:26:26 +1000 Subject: [PATCH 036/149] * Test out a dec offset --- pocs/state/states/default/observing.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pocs/state/states/default/observing.py b/pocs/state/states/default/observing.py index ae406a837..6a108b929 100644 --- a/pocs/state/states/default/observing.py +++ b/pocs/state/states/default/observing.py @@ -21,6 +21,9 @@ def on_enter(event_data): pocs.say("Observation interrupted!") break + dec_offset = 11 + pocs.observatory.mount.query('move_ms_north', '{:05.0f}'.format(dec_offset)) + pocs.logger.debug('Waiting for images: {} seconds'.format(wait_time)) pocs.status() From ac0c1289d13725eb985045ab1c57f0a850cde84a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 14:36:32 +1000 Subject: [PATCH 037/149] * Catch error if zeromq port is already taken --- bin/pocs_shell | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index ab2e746ec..f60481493 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -67,13 +67,22 @@ class PocsShell(Cmd): print_info("Starting messaging") # Send commands to POCS via this publisher - self.cmd_publisher = PanMessaging.create_publisher(self.cmd_pub_port) + try: + self.cmd_publisher = PanMessaging.create_publisher(self.cmd_pub_port) + except Exception as e: + print_warning("Can't start command publisher: {}".format(e)) # Receive messages from POCS via this subscriber - self.msg_subscriber = PanMessaging.create_subscriber(self.msg_sub_port) + try: + self.msg_subscriber = PanMessaging.create_subscriber(self.msg_sub_port) + except Exception as e: + print_warning("Can't start message subscriber: {}".format(e)) # Send messages to PAWS - self.msg_publisher = PanMessaging.create_publisher(self.msg_pub_port) + try: + self.msg_publisher = PanMessaging.create_publisher(self.msg_pub_port) + except Exception as e: + print_warning("Can't start message publisher: {}".format(e)) def do_setup_pocs(self, *arg): """ Setup and initialize a POCS instance """ From cd77391a9d62478f441a12c3c582c2de0e12906c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 14:43:02 +1000 Subject: [PATCH 038/149] * Change order of setting up messaging --- bin/pocs_shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index f60481493..f70df91e8 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -110,13 +110,13 @@ class PocsShell(Cmd): *arg {str} -- Can pass arguments through to `do_connect` """ if self.pocs is not None: + self.pocs.has_messaging = True + if self.msg_subscriber is None: self.do_start_messaging() print_info("Starting POCS - Press Ctrl-c to interrupt") - self.pocs.has_messaging = True - try: self.pocs.run() except KeyboardInterrupt: From 575d3c2f4596e052c6dc5db9e742debecc47fd19 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 14:51:17 +1000 Subject: [PATCH 039/149] * More checking of the zeromq ports --- pocs/core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pocs/core.py b/pocs/core.py index 38ec5f110..fc6ddbe97 100644 --- a/pocs/core.py +++ b/pocs/core.py @@ -438,7 +438,10 @@ def _setup_messaging(self): msg_port = self.config['messaging']['msg_port'] def create_forwarder(port): - PanMessaging.create_forwarder(port, port + 1) + try: + PanMessaging.create_forwarder(port, port + 1) + except Exception: + pass cmd_forwarder_process = Process(target=create_forwarder, args=(cmd_port,), name='CmdForwarder') cmd_forwarder_process.start() From 05f4797d5736afedf79fd56fb09e64d56564618d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 15:11:12 +1000 Subject: [PATCH 040/149] * Add center info to offset info --- pocs/images.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pocs/images.py b/pocs/images.py index 3f5dc527e..7febe7931 100644 --- a/pocs/images.py +++ b/pocs/images.py @@ -238,10 +238,12 @@ def compute_offset(self, ref, units='arcsec', rotation=True): selfHA = self.HA else: selfHA = self.header_HA + if self.Dec: selfDec = self.Dec else: selfDec = self.header_Dec + if ref.HA: refHA = ref.HA else: @@ -257,6 +259,9 @@ def compute_offset(self, ref, units='arcsec', rotation=True): 'Dec': selfDec.to(u.degree).value, 'Dec unit': 'deg', + 'center_dec': self.Dec.value, + 'center_ra': self.RA.value, + 'refimage': ref.fits_file, 'reftime': ref.midtime.to_datetime().isoformat(), 'refHA': refHA.to(u.hourangle).value, @@ -277,6 +282,7 @@ def compute_offset(self, ref, units='arcsec', rotation=True): offset_deg = self.wcs.pixel_scale_matrix.dot(deltapix) info['offsetX'] = (offset_deg[0] * u.degree).to(u.arcsecond).value info['offsetY'] = (offset_deg[1] * u.degree).to(u.arcsecond).value + return info From 24492b6141aad4064bc77e55e2c6d8ebcd7a249c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 6 Apr 2017 15:36:21 +1000 Subject: [PATCH 041/149] * Handle missing center info if not solved --- pocs/images.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pocs/images.py b/pocs/images.py index 7febe7931..fe9096a66 100644 --- a/pocs/images.py +++ b/pocs/images.py @@ -259,9 +259,6 @@ def compute_offset(self, ref, units='arcsec', rotation=True): 'Dec': selfDec.to(u.degree).value, 'Dec unit': 'deg', - 'center_dec': self.Dec.value, - 'center_ra': self.RA.value, - 'refimage': ref.fits_file, 'reftime': ref.midtime.to_datetime().isoformat(), 'refHA': refHA.to(u.hourangle).value, @@ -273,6 +270,12 @@ def compute_offset(self, ref, units='arcsec', rotation=True): 'offset units': units, } + try: + info['center_dec'] = self.Dec.value + info['center_ra'] = self.RA.value + except Exception: + pass + if units in ['pix', 'pixel']: info['offsetX'] = offset_pix['X'].to(u.pixel).value info['offsetY'] = offset_pix['Y'].to(u.pixel).value From 1d99d89719114dd6e6aad223868150a0f09e2e42 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 12:10:36 +1000 Subject: [PATCH 042/149] Small cleanup items --- pocs/camera/simulator.py | 10 ++++++---- pocs/observatory.py | 3 --- pocs/utils/database.py | 3 ++- resources/targets/simple.yaml | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pocs/camera/simulator.py b/pocs/camera/simulator.py index 3095659d0..ee83fc5f2 100644 --- a/pocs/camera/simulator.py +++ b/pocs/camera/simulator.py @@ -1,9 +1,8 @@ import os -import subprocess +import random from threading import Event from threading import Timer -import random import numpy as np @@ -12,7 +11,6 @@ from astropy.time import Time from ..utils import current_time -from ..utils import error from .camera import AbstractCamera @@ -160,7 +158,11 @@ def _fake_exposure(self, seconds, start_time, filename, exposure_event, dark): # Write FITS file to requested location if os.path.dirname(filename): os.makedirs(os.path.dirname(filename), mode=0o775, exist_ok=True) - hdu_list.writeto(filename) + + try: + hdu_list.writeto(filename) + except OSError: + pass # Set event to mark exposure complete. exposure_event.set() diff --git a/pocs/observatory.py b/pocs/observatory.py index b6492b563..9654012bb 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -326,9 +326,6 @@ def analyze_recent(self): }, }) - # Compress the image - # self.logger.debug("Compressing image") - # img_utils.fpack(image_path) except error.SolveError: self.logger.warning("Can't solve field, skipping") except Exception as e: diff --git a/pocs/utils/database.py b/pocs/utils/database.py index a1ebe348d..8adfb6fc1 100644 --- a/pocs/utils/database.py +++ b/pocs/utils/database.py @@ -60,7 +60,8 @@ def insert_current(self, collection, obj, include_collection=True): Returns: str: Mongo object ID of record in `collection` """ - assert collection in self.collections, warn("Collection not available") + if include_collection: + assert collection in self.collections, warn("Collection not available") _id = None try: diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index 91c5622fd..ed87ae670 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -5,12 +5,12 @@ - name: KIC 8462852 position: 20h06m15.4536s +44d27m24.75s - priority: 130 + priority: 125 - name: HD 189733 position: 20h00m43.713s +22d42m39.07s priority: 105 - exp_time: 90 + exp_time: 100 - name: HD 209458 position: 22h03m10.7721s +18d53m03.543s @@ -30,7 +30,7 @@ - name: Wasp 2 position: 20h30m54.0s +06d25m46.0s - priority: 110 + priority: 100 - name: Wasp 77 position: 02h28m37.22s -07d03m38.45s @@ -50,7 +50,7 @@ - name: Wasp 35 position: 05h04m19.56s -06d13m47.2s - priority: 110 + priority: 100 - name: HAT-P-20 position: 07h27m39.89s +24d20m14.7s From 5f3d015acf16c45fb12717bc4f85b83178e75574 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 12:57:09 +1000 Subject: [PATCH 043/149] * Take out some of the `Image` class that is not used right now * Simple `compute_offset` to get the RA/Dec difference * Pass `location` (`EarthLocation`) to image class --- pocs/images.py | 249 ++++++++------------------------------------ pocs/observatory.py | 42 +++----- 2 files changed, 55 insertions(+), 236 deletions(-) diff --git a/pocs/images.py b/pocs/images.py index fe9096a66..5269e7d22 100644 --- a/pocs/images.py +++ b/pocs/images.py @@ -1,7 +1,5 @@ import os -import numpy as np - from astropy import units as u from astropy import wcs from astropy.coordinates import EarthLocation @@ -9,24 +7,19 @@ from astropy.coordinates import SkyCoord from astropy.io import fits from astropy.time import Time -from ccdproc import CCDData from collections import namedtuple -from skimage.feature import register_translation -from skimage.util import view_as_blocks -from pocs import PanBase -from pocs.utils import images as img_utils +from . import PanBase +from .utils import images as img_utils -PointingError = namedtuple('PointingError', ['delta_ra', 'delta_dec', 'magnitude']) +OffsetError = namedtuple('OffsetError', ['delta_ra', 'delta_dec', 'magnitude']) class Image(PanBase): - def __init__(self, fits_file, wcs_file=None): + def __init__(self, fits_file, wcs_file=None, location=None): """Object to represent a single image from a PANOPTES camera. - Instantiate the object by providing a .cr2 (or .dng) file. - Args: fits_file (str): Name of FITS file to be read (can be .fz) wcs_file (str, optional): Name of FITS file to use for WCS @@ -50,23 +43,19 @@ def __init__(self, fits_file, wcs_file=None): with fits.open(self.fits_file, 'readonly') as hdu: self.header = hdu[0].header - self.data = hdu[0].data assert 'DATE-OBS' in self.header, self.logger.warning('FITS file must contain the DATE-OBS keyword') assert 'EXPTIME' in self.header, self.logger.warning('FITS file must contain the EXPTIME keyword') - self.RGGB = CCDData(data=self.data, unit='adu', - meta=self.header, - mask=np.zeros(self.data.shape)) - # Location Information - cfg_loc = self.config['location'] - self.loc = EarthLocation(lat=cfg_loc['latitude'], - lon=cfg_loc['longitude'], - height=cfg_loc['elevation'], - ) + if location is None: + cfg_loc = self.config['location'] + location = EarthLocation(lat=cfg_loc['latitude'], + lon=cfg_loc['longitude'], + height=cfg_loc['elevation'], + ) # Time Information - self.starttime = Time(self.header['DATE-OBS'], location=self.loc) + self.starttime = Time(self.header['DATE-OBS'], location=location) self.exptime = float(self.header['EXPTIME']) * u.second self.midtime = self.starttime + (self.exptime / 2.0) self.sidereal = self.midtime.sidereal_time('apparent') @@ -74,15 +63,15 @@ def __init__(self, fits_file, wcs_file=None): # Coordinates from header keywords self.header_pointing = None - self.header_RA = None - self.header_Dec = None - self.header_HA = None + self.header_ra = None + self.header_dec = None + self.header_ha = None # Coordinates from WCS self.pointing = None - self.RA = None - self.Dec = None - self.HA = None + self.ra = None + self.dec = None + self.ha = None self.get_header_pointing() self.get_wcs_pointing() @@ -112,24 +101,6 @@ def wcs_file(self, filename): except Exception: self.logger.warn("Can't get WCS from FITS file (try solve_field)") - @property - def luminance(self): - """Luminance for the image - - Bin the image 2x2 combining each RGGB set of pixels in to a single - luminance value. - """ - if self._luminance is None: - block_size = (2, 2) - image_out = view_as_blocks(self.RGGB.data, block_size) - - for i in range(len(image_out.shape) // 2): - image_out = np.average(image_out, axis=-1) - - self._luminance = image_out - - return self._luminance - @property def pointing_error(self): """Pointing error namedtuple (delta_ra, delta_dec, magnitude) @@ -148,10 +119,10 @@ def pointing_error(self): self.solve_field() mag = self.pointing.separation(self.header_pointing) - dDec = self.pointing.dec - self.header_pointing.dec - dRA = self.pointing.ra - self.header_pointing.ra + d_dec = self.pointing.dec - self.header_pointing.dec + d_ra = self.pointing.ra - self.header_pointing.ra - self._pointing_error = PointingError(dRA.to(u.degree), dDec.to(u.degree), mag) + self._pointing_error = OffsetError(d_ra.to(u.arcsec), d_dec.to(u.arcsec), mag.to(u.arcsec)) return self._pointing_error @@ -165,11 +136,11 @@ def get_header_pointing(self): self.header_pointing = SkyCoord(ra=float(self.header['RA-MNT']) * u.degree, dec=float(self.header['DEC-MNT']) * u.degree) - self.header_RA = self.header_pointing.ra.to(u.hourangle) - self.header_Dec = self.header_pointing.dec.to(u.degree) + self.header_ra = self.header_pointing.ra.to(u.hourangle) + self.header_dec = self.header_pointing.dec.to(u.degree) # Precess to the current equinox otherwise the RA - LST method will be off. - self.header_HA = self.header_pointing.transform_to(self.FK5_Jnow).ra.to(u.hourangle) - self.sidereal + self.header_ha = self.header_pointing.transform_to(self.FK5_Jnow).ra.to(u.hourangle) - self.sidereal except Exception as e: self.logger.warning('Cannot get header pointing information: {}'.format(e)) @@ -180,17 +151,16 @@ def get_wcs_pointing(self): compared with the coordinates stored in the header. """ if self.wcs is not None: - ny, nx = self.RGGB.data.shape - decimals = self.wcs.all_pix2world(nx // 2, ny // 2, 1) + ra = self.wcs.celestial.wcs.crval[0] + dec = self.wcs.celestial.wcs.crval[1] - self.pointing = SkyCoord(ra=decimals[0] * u.degree, - dec=decimals[1] * u.degree) + self.pointing = SkyCoord(ra=ra * u.degree, dec=dec * u.degree) - self.RA = self.pointing.ra.to(u.hourangle) - self.Dec = self.pointing.dec.to(u.degree) + self.ra = self.pointing.ra.to(u.hourangle) + self.dec = self.pointing.dec.to(u.degree) # Precess to the current equinox otherwise the RA - LST method will be off. - self.HA = self.pointing.transform_to(self.FK5_Jnow).ra.to(u.hourangle) - self.sidereal + self.ha = self.pointing.transform_to(self.FK5_Jnow).ra.to(u.hourangle) - self.sidereal def solve_field(self, **kwargs): """ Solve field and populate WCS information @@ -206,87 +176,23 @@ def solve_field(self, **kwargs): self.wcs_file = solve_info['solved_fits_file'] self.get_wcs_pointing() - return solve_info - - def compute_offset(self, ref, units='arcsec', rotation=True): - """Offset information between this image and a reference - - Args: - ref (str): Refernce image, either another `Image` instance or a - filename that will be read - units (str, optional): Can be either `arcsec` or `pixel` - rotation (bool, optional): If rotation information should be included, - defaults to True - - Returns: - dict: Offset information in key/value pairs - """ - if isinstance(units, (u.Unit, u.Quantity, u.IrreducibleUnit)): - units = units.name - assert units in ['pix', 'pixel', 'arcsec'] - - if isinstance(ref, str): - assert os.path.exists(ref) - ref = Image(ref) - assert isinstance(ref, Image) - - offset_pix = compute_offset_rotation(ref.luminance, self.luminance) - offset_pix['X'] *= 2 - offset_pix['Y'] *= 2 - - if self.HA: - selfHA = self.HA - else: - selfHA = self.header_HA - - if self.Dec: - selfDec = self.Dec - else: - selfDec = self.header_Dec - - if ref.HA: - refHA = ref.HA - else: - stime_diff = (self.midtime.sidereal_time('apparent') - ref.midtime.sidereal_time('apparent')) - refHA = selfHA - stime_diff.to(u.hourangle) - - time_diff = (self.midtime - ref.midtime) - - info = {'image': self.fits_file, - 'time': self.midtime.to_datetime().isoformat(), - 'HA': selfHA.to(u.hourangle).value, - 'HA unit': 'hours', - 'Dec': selfDec.to(u.degree).value, - 'Dec unit': 'deg', - - 'refimage': ref.fits_file, - 'reftime': ref.midtime.to_datetime().isoformat(), - 'refHA': refHA.to(u.hourangle).value, + # Remove some fields + for header in ['COMMENT', 'HISTORY']: + try: + del solve_info[header] + except KeyError: + pass - 'dt': time_diff.to(u.second).value, - 'dt unit': 'seconds', - 'angle': offset_pix['angle'].to(u.degree).value, - 'angle unit': 'deg', - 'offset units': units, - } + return solve_info - try: - info['center_dec'] = self.Dec.value - info['center_ra'] = self.RA.value - except Exception: - pass + def compute_offset(self, ref_image): + assert isinstance(ref_image, Image), self.logger.warning("Must pass an Image class for reference") - if units in ['pix', 'pixel']: - info['offsetX'] = offset_pix['X'].to(u.pixel).value - info['offsetY'] = offset_pix['Y'].to(u.pixel).value - elif units == 'arcsec': - deltapix = [offset_pix['X'].to(u.pixel).value, - offset_pix['Y'].to(u.pixel).value] - offset_deg = self.wcs.pixel_scale_matrix.dot(deltapix) - info['offsetX'] = (offset_deg[0] * u.degree).to(u.arcsecond).value - info['offsetY'] = (offset_deg[1] * u.degree).to(u.arcsecond).value + mag = self.pointing.separation(ref_image.pointing) + d_dec = self.pointing.dec - ref_image.pointing.dec + d_ra = self.pointing.ra - ref_image.pointing.ra - return info + return OffsetError(d_ra.to(u.arcsec), d_dec.to(u.arcsec), mag.to(u.arcsec)) ################################################################################################## @@ -295,74 +201,3 @@ def compute_offset(self, ref, units='arcsec', rotation=True): def __str__(self): return "{}: {}".format(self.fits_file, self.header_pointing) - - -def compute_offset_rotation(im, imref, upsample_factor=20, subframe_size=200, corners=True): - """Determine rotation information between two images - - Detremine the rotation information for the center and, if `corner`, the - four corner boxes, each of `subframe_size` pixels. - - Args: - im (numpy.array): Image data - imref (numpy.array): Comparison image data - upsample_factor (int, optional): Subpixel fraction to compute - subframe_size (int, optional): Box size - corners (bool, optional): If corner boxes should be included, defaults - to True - - Returns: - dict: Rotation offset in `X`, `Y`, and `angle` - """ - assert im.shape == imref.shape - ny, nx = im.shape - - subframe_half = int(subframe_size / 2) - - # Create the center point for each of our regions - regions = {'center': (int(nx / 2), int(ny / 2)), } - offsets = {'center': None, } - - if corners: - regions.update({ - 'upper_right': (int(nx - subframe_half), int(ny - subframe_half)), - 'upper_left': (int(subframe_half), int(ny - subframe_half)), - 'lower_right': (int(nx - subframe_half), int(subframe_half)), - 'lower_left': (int(subframe_half), int(subframe_half)), - }) - - offsets.update({ - 'upper_right': None, - 'upper_left': None, - 'lower_right': None, - 'lower_left': None, - }) - - # Get im/imref offsets for each region - for region, midpoint in regions.items(): - imarr = img_utils.crop_data(im, center=midpoint, box_width=subframe_size) - imrefarr = img_utils.crop_data(imref, center=midpoint, box_width=subframe_size) - - shifts, err, h = register_translation(imrefarr, imarr, upsample_factor=upsample_factor) - offsets[region] = shifts - - # Rotate the offsets according to region - angles = [] - for region in regions.keys(): - if region != 'center': - offsets[region] -= offsets['center'] - - relpos = (regions[region][0] - regions['center'][0], - regions[region][1] - regions['center'][1]) - - theta1 = np.arctan(relpos[1] / relpos[0]) - theta2 = np.arctan((relpos[1] + offsets[region][1]) / (relpos[0] + offsets[region][0])) - angles.append(theta2 - theta1) - - angle = np.mean(angles) - - result = {'X': offsets['center'][0] * u.pix, - 'Y': offsets['center'][1] * u.pix, - 'angle': (angle * u.radian).to(u.degree)} - - return result diff --git a/pocs/observatory.py b/pocs/observatory.py index 9654012bb..84495e793 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -53,7 +53,7 @@ def __init__(self, *args, **kwargs): self.scheduler = None self._create_scheduler() - self.offset_info = None + self.current_offset_info = None self._image_dir = self.config['directories']['images'] self.logger.info('\t Observatory initialized') @@ -275,54 +275,38 @@ def analyze_recent(self): dict: Offset information """ # Clear the offset info - self.offset_info = dict() + self.current_offset_info = dict() ref_image_id, ref_image_path = self.current_observation.first_exposure try: # If we just finished the first exposure, solve the image so it can be reference if self.current_observation.current_exp == 1: - ref_image = Image(ref_image_path) + ref_image = Image(ref_image_path, location=self.earth_location) ref_solve_info = ref_image.solve_field() - try: - del ref_solve_info['COMMENT'] - except KeyError: - pass - - try: - del ref_solve_info['HISTORY'] - except KeyError: - pass - self.logger.debug("Reference Solve Info: {}".format(ref_solve_info)) else: # Get the image to compare image_id, image_path = self.current_observation.last_exposure - current_image = Image(image_path, wcs_file=ref_image_path) + current_image = Image(image_path, location=self.earth_location) solve_info = current_image.solve_field() - try: - del solve_info['COMMENT'] - except KeyError: - pass - - try: - del solve_info['HISTORY'] - except KeyError: - pass - self.logger.debug("Solve Info: {}".format(solve_info)) # Get the offset between the two - self.offset_info = current_image.compute_offset(ref_image_path) - self.logger.debug('Offset Info: {}'.format(self.offset_info)) + self.current_offset_info = current_image.compute_offset(ref_image_path) + self.logger.debug('Offset Info: {}'.format(self.current_offset_info)) # Update the observation info with the offsets self.db.observations.update({'image_id': image_id}, { '$set': { - 'offset_info': self.offset_info, + 'offset_info': { + 'd_ra': self.current_offset_info.delta_ra.value, + 'd_dec': self.current_offset_info.delta_dec.value, + 'magnitude': self.current_offset_info.magnitude.value, + } }, }) @@ -331,12 +315,12 @@ def analyze_recent(self): except Exception as e: self.logger.warning("Problem in analyzing: {}".format(e)) - return self.offset_info + return self.current_offset_info def update_tracking(self): """Update tracking with rate adjustment - Uses the `rate_adjustment` key from the `self.offset_info` + Uses the `rate_adjustment` key from the `self.current_offset_info` """ pass From aa72ddbd534fd0cccc33d3804263ca509bc24b1b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 13:49:39 +1000 Subject: [PATCH 044/149] * Adding tracking adjustments to check ms offsets --- pocs/mount/mount.py | 12 ++++++++++++ pocs/observatory.py | 21 ++++++++++++++++++++- pocs/state/states/default/observing.py | 3 --- pocs/state/states/default/tracking.py | 6 +++++- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/pocs/mount/mount.py b/pocs/mount/mount.py index 7f7ef01b8..7b41737d9 100644 --- a/pocs/mount/mount.py +++ b/pocs/mount/mount.py @@ -70,6 +70,7 @@ def __init__(self, location, commands=None, *args, **kwargs self._is_home = False self._state = 'Parked' + self.sidereal_rate = ((360 * u.degree).to(u.arcsec) / (86164 * u.second)) self.guide_rate = 0.9 # Sidereal self._tracking_rate = 1.0 # Sidereal self._tracking = 'Sidereal' @@ -471,6 +472,17 @@ def set_tracking_rate(self, direction='ra', delta=1.0): """Sets the tracking rate for the mount """ raise NotImplementedError + def get_ms_offset(self, offset): + """ Get offset in milliseconds at current speed + + Args: + offset (float): Offset in arcseconds + + Returns: + float: Offset in milliseconds at current speed + """ + return (offset / (self.sidereal_rate * self.guide_rate)).to(u.ms) + def query(self, cmd, params=None): """ Sends a query to TheSkyX and returns response. diff --git a/pocs/observatory.py b/pocs/observatory.py index 84495e793..750172ae1 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -306,6 +306,7 @@ def analyze_recent(self): 'd_ra': self.current_offset_info.delta_ra.value, 'd_dec': self.current_offset_info.delta_dec.value, 'magnitude': self.current_offset_info.magnitude.value, + 'unit': 'arcsec' } }, }) @@ -322,7 +323,25 @@ def update_tracking(self): Uses the `rate_adjustment` key from the `self.current_offset_info` """ - pass + dec_offset = self.current_offset_info.delta_dec + dec_ms = self.mount.get_ms_offset(dec_offset) + if dec_offset >= 0: + dec_direction = 'south' + else: + dec_direction = 'north' + + ra_offset = self.current_offset_info.delta_ra + ra_ms = self.mount.get_ms_offset(ra_offset) + if ra_offset >= 0: + ra_direction = 'east' + else: + ra_direction = 'west' + + self.logger.info("Adjusting mount dec: {} {}".format(dec_direction, dec_ms)) + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + + self.logger.info("Adjusting mount ra: {} {}".format(ra_direction, ra_ms)) + self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) def get_standard_headers(self, observation=None): """Get a set of standard headers diff --git a/pocs/state/states/default/observing.py b/pocs/state/states/default/observing.py index 6a108b929..ae406a837 100644 --- a/pocs/state/states/default/observing.py +++ b/pocs/state/states/default/observing.py @@ -21,9 +21,6 @@ def on_enter(event_data): pocs.say("Observation interrupted!") break - dec_offset = 11 - pocs.observatory.mount.query('move_ms_north', '{:05.0f}'.format(dec_offset)) - pocs.logger.debug('Waiting for images: {} seconds'.format(wait_time)) pocs.status() diff --git a/pocs/state/states/default/tracking.py b/pocs/state/states/default/tracking.py index d8fe2a266..601447041 100644 --- a/pocs/state/states/default/tracking.py +++ b/pocs/state/states/default/tracking.py @@ -3,6 +3,10 @@ def on_enter(event_data): pocs = event_data.model pocs.say("Checking our tracking") - pocs.observatory.update_tracking() + try: + pocs.observatory.update_tracking() + except Exception as e: + pocs.logger.warning("Problem adjusting tracking: {}".format(e)) + pocs.say("Done with tracking adjustment, going to observe") pocs.next_state = 'observing' From 818cf3950489b897e67e1b65c7db6f3f81e8604d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 13:59:16 +1000 Subject: [PATCH 045/149] `PointingError` -> `OffsetError` --- pocs/tests/test_images.py | 6 +++--- pocs/utils/images.py | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pocs/tests/test_images.py b/pocs/tests/test_images.py index 71e5cbbbf..bfc6041a8 100644 --- a/pocs/tests/test_images.py +++ b/pocs/tests/test_images.py @@ -2,7 +2,7 @@ import pytest from pocs.images import Image -from pocs.images import PointingError +from pocs.images import OffsetError from pocs.utils.error import SolveError from pocs.utils.error import Timeout @@ -115,7 +115,7 @@ def test_pointing_error_no_wcs(unsolved_fits_file): def test_pointing_error_passed_wcs(unsolved_fits_file, solved_fits_file): im0 = Image(unsolved_fits_file, wcs_file=solved_fits_file) - assert isinstance(im0.pointing_error, PointingError) + assert isinstance(im0.pointing_error, OffsetError) def test_pointing_error(solved_fits_file): @@ -124,7 +124,7 @@ def test_pointing_error(solved_fits_file): im0.solve_field(verbose=True, replace=False, radius=4) perr = im0.pointing_error - assert isinstance(perr, PointingError) + assert isinstance(perr, OffsetError) assert (perr.delta_ra.value - 1.647535444553057) < 1e-5 assert (perr.delta_dec.value - 1.560722632731533) < 1e-5 diff --git a/pocs/utils/images.py b/pocs/utils/images.py index 6f9aca90c..423508a37 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -2,7 +2,6 @@ import shutil import subprocess -from collections import namedtuple from dateutil import parser as date_parser from json import loads @@ -19,8 +18,6 @@ from pocs.utils import current_time from pocs.utils import error -PointingError = namedtuple('PointingError', ['delta_ra', 'delta_dec', 'separation']) - def solve_field(fname, timeout=15, solve_opts=[], **kwargs): """ Plate solves an image. From 3fd2fcdb8e84f252ddada4d7f169d654ef266f18 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 14:06:11 +1000 Subject: [PATCH 046/149] * Adding some transits --- resources/targets/simple.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index ed87ae670..589904958 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -62,7 +62,7 @@ - name: Tres 3 position: 17h52m07.02s +37d32m46.2012s - priority: 100 + priority: 120 - name: EPIC-211089792 position: 04h10m40.955s +24d24m07.35s @@ -71,6 +71,10 @@ name: HAT-P-1 position: 22h57m47.0s +38d40m30.0s priority: 100 +- + name: HAT-P-36 + position: 12h33m03.909s +44d54m55.18s + priority: 120 - name: M42 position: 05h35m17.2992s -05d23m27.996s From bbe8bb1747a500c7dbe7a21e8372cf64a2cc1be4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 14:21:17 +1000 Subject: [PATCH 047/149] * Fixing tests for variable name change --- pocs/tests/test_images.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pocs/tests/test_images.py b/pocs/tests/test_images.py index bfc6041a8..28db45ac9 100644 --- a/pocs/tests/test_images.py +++ b/pocs/tests/test_images.py @@ -80,9 +80,9 @@ def test_solve_field_unsolved(unsolved_fits_file): assert im0.wcs is not None assert im0.wcs_file is not None assert isinstance(im0.pointing, SkyCoord) - assert im0.RA is not None - assert im0.Dec is not None - assert im0.HA is not None + assert im0.ra is not None + assert im0.dec is not None + assert im0.ha is not None # Remove extra files os.remove(unsolved_fits_file.replace('.fits', '.solved')) @@ -96,9 +96,9 @@ def test_solve_field_solved(solved_fits_file): assert im0.wcs is not None assert im0.wcs_file is not None assert im0.pointing is not None - assert im0.RA is not None - assert im0.Dec is not None - assert im0.HA is not None + assert im0.ra is not None + assert im0.dec is not None + assert im0.ha is not None im0.solve_field(verbose=True, radius=4) From b6ffca6ec772bca209e0e534183ef529781d57d4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 14:44:56 +1000 Subject: [PATCH 048/149] Adjust image tests --- pocs/tests/test_images.py | 47 ++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/pocs/tests/test_images.py b/pocs/tests/test_images.py index 28db45ac9..bc2b0c5cf 100644 --- a/pocs/tests/test_images.py +++ b/pocs/tests/test_images.py @@ -6,6 +6,7 @@ from pocs.utils.error import SolveError from pocs.utils.error import Timeout +from astropy import units as u from astropy.coordinates import SkyCoord @@ -126,40 +127,40 @@ def test_pointing_error(solved_fits_file): perr = im0.pointing_error assert isinstance(perr, OffsetError) - assert (perr.delta_ra.value - 1.647535444553057) < 1e-5 - assert (perr.delta_dec.value - 1.560722632731533) < 1e-5 - assert (perr.magnitude.value - 1.9445870862060288) < 1e-5 + assert (perr.delta_ra.to(u.degree).value - 1.647535444553057) < 1e-5 + assert (perr.delta_dec.to(u.degree).value - 1.560722632731533) < 1e-5 + assert (perr.magnitude.to(u.degree).value - 1.9445870862060288) < 1e-5 -def test_compute_offset_arcsec(solved_fits_file, unsolved_fits_file): - img0 = Image(solved_fits_file) - img1 = Image(unsolved_fits_file) +# def test_compute_offset_arcsec(solved_fits_file, unsolved_fits_file): +# img0 = Image(solved_fits_file) +# img1 = Image(unsolved_fits_file) - offset_info = img0.compute_offset(img1) +# offset_info = img0.compute_offset(img1) - assert offset_info['offsetX'] - 3.9686712667745043 < 1e-5 - assert offset_info['offsetY'] - 17.585827075244445 < 1e-5 +# assert offset_info['offsetX'] - 3.9686712667745043 < 1e-5 +# assert offset_info['offsetY'] - 17.585827075244445 < 1e-5 -def test_compute_offset_pixel(solved_fits_file, unsolved_fits_file): - img0 = Image(solved_fits_file) - img1 = Image(unsolved_fits_file) +# def test_compute_offset_pixel(solved_fits_file, unsolved_fits_file): +# img0 = Image(solved_fits_file) +# img1 = Image(unsolved_fits_file) - offset_info = img0.compute_offset(img1, units='pixel') +# offset_info = img0.compute_offset(img1, units='pixel') - assert offset_info['offsetX'] == 1.7 - assert offset_info['offsetY'] == 0.4 +# assert offset_info['offsetX'] == 1.7 +# assert offset_info['offsetY'] == 0.4 - offset_info_opposite = img1.compute_offset(img0, units='pixel') +# offset_info_opposite = img1.compute_offset(img0, units='pixel') - assert offset_info_opposite['offsetX'] == -1 * offset_info['offsetX'] - assert offset_info_opposite['offsetY'] == -1 * offset_info['offsetY'] +# assert offset_info_opposite['offsetX'] == -1 * offset_info['offsetX'] +# assert offset_info_opposite['offsetY'] == -1 * offset_info['offsetY'] -def test_compute_offset_string(solved_fits_file, unsolved_fits_file): - img0 = Image(solved_fits_file) +# def test_compute_offset_string(solved_fits_file, unsolved_fits_file): +# img0 = Image(solved_fits_file) - offset_info = img0.compute_offset(unsolved_fits_file) +# offset_info = img0.compute_offset(unsolved_fits_file) - assert offset_info['offsetX'] - 3.9686712667745043 < 1e-5 - assert offset_info['offsetY'] - 17.585827075244445 < 1e-5 +# assert offset_info['offsetX'] - 3.9686712667745043 < 1e-5 +# assert offset_info['offsetY'] - 17.585827075244445 < 1e-5 From eca09cc2f5929ef822772ac94d1d6c40b8b01f08 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 17:02:29 +1000 Subject: [PATCH 049/149] * Pass an `Image` rather than a path --- pocs/observatory.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 750172ae1..e49d0788f 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -291,12 +291,13 @@ def analyze_recent(self): image_id, image_path = self.current_observation.last_exposure current_image = Image(image_path, location=self.earth_location) + ref_image = Image(ref_image_path, location=self.earth_location) solve_info = current_image.solve_field() self.logger.debug("Solve Info: {}".format(solve_info)) # Get the offset between the two - self.current_offset_info = current_image.compute_offset(ref_image_path) + self.current_offset_info = current_image.compute_offset(ref_image) self.logger.debug('Offset Info: {}'.format(self.current_offset_info)) # Update the observation info with the offsets From 4241d8f1a98d11a77d6f7c9b9abafbfcf8814f10 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 18:00:25 +1000 Subject: [PATCH 050/149] * Only adjust if more than one ms --- pocs/observatory.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index e49d0788f..65ed2a1d8 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -1,4 +1,5 @@ import os +import time from collections import OrderedDict from datetime import datetime @@ -338,11 +339,16 @@ def update_tracking(self): else: ra_direction = 'west' - self.logger.info("Adjusting mount dec: {} {}".format(dec_direction, dec_ms)) - self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + if dec_ms.value >= 1.: + self.logger.info("Adjusting mount dec: {} {}".format(dec_direction, dec_ms)) + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) - self.logger.info("Adjusting mount ra: {} {}".format(ra_direction, ra_ms)) - self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) + if ra_ms.value >= 1.: + self.logger.info("Adjusting mount ra: {} {}".format(ra_direction, ra_ms)) + self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) + + while self.mount.is_slewing: + time.sleep(1) def get_standard_headers(self, observation=None): """Get a set of standard headers From b484333ffe271278355877b921987151c95de8f7 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 18:26:08 +1000 Subject: [PATCH 051/149] * Show which values are updating --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 65ed2a1d8..508adae04 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -339,12 +339,12 @@ def update_tracking(self): else: ra_direction = 'west' + self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) if dec_ms.value >= 1.: - self.logger.info("Adjusting mount dec: {} {}".format(dec_direction, dec_ms)) self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + self.logger.info("Adjusting mount ra: {} {} {}".format(ra_direction, ra_ms, ra_offset)) if ra_ms.value >= 1.: - self.logger.info("Adjusting mount ra: {} {}".format(ra_direction, ra_ms)) self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) while self.mount.is_slewing: From eec05ebf6f032069f592c65956dc853905a375b2 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 18:33:59 +1000 Subject: [PATCH 052/149] * ADding target --- resources/targets/simple.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index 589904958..3449a9b0f 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -31,6 +31,10 @@ name: Wasp 2 position: 20h30m54.0s +06d25m46.0s priority: 100 +- + name: Wasp 24 + position: 15h08m51.739s +02d20m35.95s + priority: 100 - name: Wasp 77 position: 02h28m37.22s -07d03m38.45s From 5e1d004c50bae404952a335c2a2c4b0e0b904660 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 18:49:58 +1000 Subject: [PATCH 053/149] Explictly set guide rate (NOTE: CHANGE ME) --- pocs/mount/mount.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/mount/mount.py b/pocs/mount/mount.py index 7b41737d9..05724e047 100644 --- a/pocs/mount/mount.py +++ b/pocs/mount/mount.py @@ -481,7 +481,7 @@ def get_ms_offset(self, offset): Returns: float: Offset in milliseconds at current speed """ - return (offset / (self.sidereal_rate * self.guide_rate)).to(u.ms) + return (offset / (self.sidereal_rate * 0.9)).to(u.ms) def query(self, cmd, params=None): """ Sends a query to TheSkyX and returns response. From 62a22122ad24905b6c1d2b27e3a5f176d466a1ff Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 19:47:19 +1000 Subject: [PATCH 054/149] * Wait for tracking adjustments to finish --- pocs/observatory.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 508adae04..f2aed0bf1 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -328,9 +328,9 @@ def update_tracking(self): dec_offset = self.current_offset_info.delta_dec dec_ms = self.mount.get_ms_offset(dec_offset) if dec_offset >= 0: - dec_direction = 'south' - else: dec_direction = 'north' + else: + dec_direction = 'south' ra_offset = self.current_offset_info.delta_ra ra_ms = self.mount.get_ms_offset(ra_offset) @@ -347,8 +347,7 @@ def update_tracking(self): if ra_ms.value >= 1.: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) - while self.mount.is_slewing: - time.sleep(1) + time.sleep((dec_ms.value + ra_ms.value + 3000) / 1000) def get_standard_headers(self, observation=None): """Get a set of standard headers From 66b3a06569585f799da4c3cb412d745f8ab70aa4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 20:16:05 +1000 Subject: [PATCH 055/149] Switch RA --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index f2aed0bf1..d6e5552e9 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -335,9 +335,9 @@ def update_tracking(self): ra_offset = self.current_offset_info.delta_ra ra_ms = self.mount.get_ms_offset(ra_offset) if ra_offset >= 0: - ra_direction = 'east' - else: ra_direction = 'west' + else: + ra_direction = 'east' self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) if dec_ms.value >= 1.: From 78a8d2d842c1ab3bcdb872562f547ac78c1e8cf9 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 21:33:34 +1000 Subject: [PATCH 056/149] * Don't do negative time --- pocs/observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index d6e5552e9..db0343393 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -347,7 +347,7 @@ def update_tracking(self): if ra_ms.value >= 1.: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) - time.sleep((dec_ms.value + ra_ms.value + 3000) / 1000) + time.sleep(abs((dec_ms.value + ra_ms.value + 3000) / 1000)) def get_standard_headers(self, observation=None): """Get a set of standard headers From 51747f9faf177fd8ea8b5d0d8f276f608da8b1b8 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Fri, 7 Apr 2017 22:02:02 +1000 Subject: [PATCH 057/149] Switch direction --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index db0343393..efff70bbb 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -335,9 +335,9 @@ def update_tracking(self): ra_offset = self.current_offset_info.delta_ra ra_ms = self.mount.get_ms_offset(ra_offset) if ra_offset >= 0: - ra_direction = 'west' - else: ra_direction = 'east' + else: + ra_direction = 'west' self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) if dec_ms.value >= 1.: From 9c7e2a3e9b507ca5c7967cb0b3d2d3aa9857bc5a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 11:15:40 +1000 Subject: [PATCH 058/149] Reset targets --- resources/targets/simple.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index 3449a9b0f..7052adbea 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -66,7 +66,7 @@ - name: Tres 3 position: 17h52m07.02s +37d32m46.2012s - priority: 120 + priority: 100 - name: EPIC-211089792 position: 04h10m40.955s +24d24m07.35s From 0c4bf104cac86f70d65593500332e44ffdb678e5 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 15:39:40 +1000 Subject: [PATCH 059/149] Adding more targets (need a better way) --- resources/targets/simple.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index 7052adbea..b10011369 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -63,6 +63,10 @@ name: Qatar-1 position: 20h13m32.0s +65d09m43.0s priority: 100 +- + name: Qatar-2 + position: 13h50m37.409s -06d48m14.4101s + priority: 100 - name: Tres 3 position: 17h52m07.02s +37d32m46.2012s @@ -78,7 +82,11 @@ - name: HAT-P-36 position: 12h33m03.909s +44d54m55.18s - priority: 120 + priority: 100 +- + name: HAT-P-37 + position: 18h57m11.058s +51d16m08.8601s + priority: 100 - name: M42 position: 05h35m17.2992s -05d23m27.996s From a82d730a3d11c903e4019133a067da20d04ff9a8 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 16:41:44 +1000 Subject: [PATCH 060/149] Serial * Using a buffered IO writer (sesnors still giving a few problems) --- pocs/observatory.py | 12 +++++------- pocs/utils/rs232.py | 8 +++++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index efff70bbb..6bea82f9b 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -347,8 +347,6 @@ def update_tracking(self): if ra_ms.value >= 1.: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) - time.sleep(abs((dec_ms.value + ra_ms.value + 3000) / 1000)) - def get_standard_headers(self, observation=None): """Get a set of standard headers @@ -368,17 +366,17 @@ def get_standard_headers(self, observation=None): self.logger.debug("Getting headers for : {}".format(observation)) - time = current_time() - moon = get_moon(time, self.observer.location) + t0 = current_time() + moon = get_moon(t0, self.observer.location) headers = { - 'airmass': self.observer.altaz(time, field).secz.value, + 'airmass': self.observer.altaz(t0, field).secz.value, 'creator': "POCSv{}".format(self.__version__), 'elevation': self.location.get('elevation').value, - 'ha_mnt': self.observer.target_hour_angle(time, field).value, + 'ha_mnt': self.observer.target_hour_angle(t0, field).value, 'latitude': self.location.get('latitude').value, 'longitude': self.location.get('longitude').value, - 'moon_fraction': self.observer.moon_illumination(time), + 'moon_fraction': self.observer.moon_illumination(t0), 'moon_separation': field.coord.separation(moon).value, 'observer': self.config.get('name', ''), 'origin': 'Project PANOPTES', diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index dbc16fdbe..be569a473 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -1,6 +1,9 @@ import serial as serial import time +from io import BufferedRWPair +from io import TextIOWrapper + from collections import deque from threading import Thread @@ -36,6 +39,9 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self._is_listening = False self.loop_delay = 2. + self._serial_io = TextIOWrapper(BufferedRWPair(self.ser.port, self.ser.port), + newline='\r\n', encoding='ascii', line_buffering=True) + if self.is_threaded: self.logger.debug("Using threads (multiprocessing)") self.process = Thread(target=self.receiving_function, args=(self.queue,)) @@ -141,7 +147,7 @@ def read(self): delay = 0.5 while True and retry_limit: - response_string = self.ser.readline(self.ser.inWaiting()).decode() + response_string = self._serial_io.readline().decode() if response_string > '': break From 4834e6700ecf73114c6db09082e56fa29c87d65d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 16:49:37 +1000 Subject: [PATCH 061/149] Cleaning up new serial buffer interface --- pocs/utils/rs232.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index be569a473..0704811a1 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -17,7 +17,7 @@ class SerialData(PanBase): Main serial class """ - def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): + def __init__(self, port=None, baudrate=115200, threaded=True, name="serial_data"): PanBase.__init__(self) try: @@ -29,17 +29,19 @@ def __init__(self, port=None, baudrate=9600, threaded=True, name="serial_data"): self.ser.bytesize = serial.EIGHTBITS self.ser.parity = serial.PARITY_NONE self.ser.stopbits = serial.STOPBITS_ONE - self.ser.timeout = 0.1 - self.ser.xonxoff = 0 - self.ser.rtscts = 0 - self.ser.interCharTimeout = None + self.ser.timeout = 1.0 + self.ser.xonxoff = False + self.ser.rtscts = False + self.ser.dsrdtr = False + self.ser.write_timeout = False + self.ser.open() self.name = name self.queue = deque([], 100) self._is_listening = False self.loop_delay = 2. - self._serial_io = TextIOWrapper(BufferedRWPair(self.ser.port, self.ser.port), + self._serial_io = TextIOWrapper(BufferedRWPair(self.ser, self.ser), newline='\r\n', encoding='ascii', line_buffering=True) if self.is_threaded: From b3bac5e44bf877949e8b1ffe8eac0ae9b2009f6e Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 16:50:35 +1000 Subject: [PATCH 062/149] * `decode` not needed with buffer --- pocs/utils/rs232.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 0704811a1..2a5020418 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -149,7 +149,7 @@ def read(self): delay = 0.5 while True and retry_limit: - response_string = self._serial_io.readline().decode() + response_string = self._serial_io.readline() if response_string > '': break From d7032fe444ca35966efe802de1ed5d751b757090 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 17:07:14 +1000 Subject: [PATCH 063/149] Update write interface for buffered --- pocs/utils/rs232.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 2a5020418..770ca0440 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -135,7 +135,7 @@ def write(self, value): assert self.ser.isOpen() # self.logger.debug('Serial write: {}'.format(value)) - return self.ser.write(value.encode()) + return self._serial_io.write() def read(self): """ From ac67a06195e7aa67afcdc98c8b3112115683f76c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 17:11:00 +1000 Subject: [PATCH 064/149] How about actually writing the value? --- pocs/utils/rs232.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 770ca0440..d94582f9d 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -135,7 +135,7 @@ def write(self, value): assert self.ser.isOpen() # self.logger.debug('Serial write: {}'.format(value)) - return self._serial_io.write() + return self._serial_io.write(value) def read(self): """ From 32c22d3fbfc56bdb714d3d9daddc961faf75139c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 17:22:25 +1000 Subject: [PATCH 065/149] Serial * Only use the buffered r/w for threaded (sensors). Mount need snot --- pocs/utils/rs232.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index d94582f9d..c7952ea70 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -41,10 +41,10 @@ def __init__(self, port=None, baudrate=115200, threaded=True, name="serial_data" self._is_listening = False self.loop_delay = 2. - self._serial_io = TextIOWrapper(BufferedRWPair(self.ser, self.ser), - newline='\r\n', encoding='ascii', line_buffering=True) - if self.is_threaded: + self._serial_io = TextIOWrapper(BufferedRWPair(self.ser, self.ser), + newline='\r\n', encoding='ascii', line_buffering=True) + self.logger.debug("Using threads (multiprocessing)") self.process = Thread(target=self.receiving_function, args=(self.queue,)) self.process.daemon = True @@ -135,7 +135,12 @@ def write(self, value): assert self.ser.isOpen() # self.logger.debug('Serial write: {}'.format(value)) - return self._serial_io.write(value) + if self.is_threaded: + response = self._serial_io.write(value) + else: + response = self.ser.write(value.encode()) + + return response def read(self): """ @@ -149,7 +154,11 @@ def read(self): delay = 0.5 while True and retry_limit: - response_string = self._serial_io.readline() + if self.is_threaded: + response_string = self._serial_io.readline() + else: + response_string = self.ser.readline(self.ser.inWaiting()).decode() + if response_string > '': break From 7bd1474d013198321e199fd933991b96da806052 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 17:28:01 +1000 Subject: [PATCH 066/149] Specify the baudrate for the mount --- pocs/mount/serial.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/mount/serial.py b/pocs/mount/serial.py index 63c23fad1..5de765796 100644 --- a/pocs/mount/serial.py +++ b/pocs/mount/serial.py @@ -21,7 +21,7 @@ def __init__(self, *args, **kwargs): self.logger.error('No mount port specified, cannot create mount\n {}'.format(self.config['mount'])) try: - self.serial = rs232.SerialData(port=self._port, threaded=False) + self.serial = rs232.SerialData(port=self._port, threaded=False, baudrate=9600) except Exception as err: self.serial = None raise error.MountNotFound(err) @@ -106,7 +106,7 @@ def write(self, cmd): """ assert self.is_initialized, self.logger.warning('Mount has not been initialized') - self.serial.clear_buffer() + # self.serial.clear_buffer() # self.logger.debug("Mount Query: {}".format(cmd)) self.serial.write(cmd) From 5ff13b77feff0eb0eea99cea430cf5bffe364e06 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 20:40:39 +1000 Subject: [PATCH 067/149] * Script for performing alignment --- scripts/analyze_polar_alignment_test.py | 237 ++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 scripts/analyze_polar_alignment_test.py diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py new file mode 100644 index 000000000..11009de4a --- /dev/null +++ b/scripts/analyze_polar_alignment_test.py @@ -0,0 +1,237 @@ +import os +import time + +from argparse import ArgumentParser +from multiprocessing import Process +from multiprocessing import Queue +from subprocess import TimeoutExpired + +from matplotlib import pyplot as plt + +from skimage.feature import canny +from skimage.transform import hough_circle +from skimage.transform import hough_circle_peaks + +from astropy.io import fits +from astropy.utils import console +from astropy.visualization import SqrtStretch +from astropy.visualization.mpl_normalize import ImageNormalize + +import numpy as np + +from pocs import POCS +from pocs.utils import current_time +from pocs.utils import images as img_utils + +norm = ImageNormalize(stretch=SqrtStretch()) + +pocs = None +mount = None + +verbose = False + + +def polar_rotation(exp_time=300, base_dir=None, **kwargs): + assert base_dir is not None, print_warning("base_dir cannot be empty") + + print_info('Performing polar rotation test, slewing to home') + mount.unpark() + + while not mount.is_home: + time.sleep(2) + + analyze_fn = None + + print_info('At home position, taking {} sec exposure'.format(exp_time)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/pole_{}.cr2'.format(base_dir, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + if cam.is_primary: + analyze_fn = fn + + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + + return analyze_fn + + +def mount_rotation(base_dir=None, **kwargs): + print_info("Doing rotation test") + exp_time = 25 + mount.move_direction(direction='west', seconds=11) + + # Start exposing on cameras + for direction in ['east', 'west']: + print_info("Rotating to {}".format(direction)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + + # Move mount + mount.move_direction(direction=direction, seconds=21) + + # Get exposures + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image( + fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + + print_info("Done with tests, parking mount") + mount.park() + + +def analyze_polar_rotation(pole_fn, return_queue): + d1 = fits.getdata(pole_fn) + d1 = d1 / d1.max() + d2 = d1.copy() + + pole_edges = canny(d2, sigma=2.0) + + pole_hough_radii = np.arange(1000, 4500, 100) + pole_hough_res = hough_circle(pole_edges, pole_hough_radii) + pole_accums, pole_cx, pole_cy, pole_radii = hough_circle_peaks(pole_hough_res, pole_hough_radii, total_num_peaks=3) + + return_queue.put(['polar', pole_cx[-1], pole_cy[-1]]) + + +def analyze_ra_rotation(rotate_fn, return_queue): + d0 = fits.getdata(rotate_fn) + d0 = d0 / d0.max() + + # Get edges for rotation + rotate_edges = canny(d0, sigma=2.0, low_threshold=.1, high_threshold=.6) + + rotate_hough_radii = np.arange(200, 800, 50) + rotate_hough_res = hough_circle(rotate_edges, rotate_hough_radii) + rotate_accums, rotate_cx, rotate_cy, rotate_radii = \ + hough_circle_peaks(rotate_hough_res, rotate_hough_radii, total_num_peaks=3) + + return_queue.put(['rotate', rotate_cx[-1], rotate_cy[-1]]) + + +def plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn=None): + assert plot_fn is not None, print_warning("Output plot name required") + + data = fits.getdata(pole_fn) + fits.getdata(rotate_fn) + + pole_cx, pole_cy = pole_center + rotate_cx, rotate_cy = rotate_center + + fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(30, 25)) + + ax.scatter(pole_cx, pole_cy, color='r', marker='x', lw=5) + ax.scatter(rotate_cx, rotate_cy, color='r', marker='x', lw=5) + + ax.imshow(data, cmap='Greys_r', norm=norm) + ax.arrow(rotate_cx, rotate_cy, pole_cx - rotate_cx, pole_cy - rotate_cy, fc='r', ec='r') + fig.savefig(plot_fn) + + +def print_info(msg): + if verbose: + console.color_print(msg, 'lightgreen') + + +def print_warning(msg): + if verbose: + console.color_print(msg, 'yellow') + + +def print_error(msg): + if verbose: + console.color_print(msg, 'red') + + +if __name__ == '__main__': + parser = ArgumentParser(description='Perform a polar alignment test') + parser.add_argument('--exp-time', default=300, help='Exposure time for polar rotation') + parser.add_argument('--base-dir', default='{}/images/drift_align'.format(os.getenv('PANDIR')), + help='Directory to store images') + parser.add_argument('--verbose', action="store_true", default='False', help='Verbose') + + args = parser.parse_args() + + if args.verbose: + verbose = True + + print_info("Setting up POCS") + pocs = POCS(messaging=True) + pocs.initialize() + mount = pocs.observatory.mount + + start_time = current_time(flatten=True) + + return_queue = Queue() + + base_dir = '{}/{}/'.format(args.base_dir, start_time) + plot_fn = '{}/{}_center_overlay.png'.format(base_dir, start_time) + + # Polar Rotation + pole_fn = polar_rotation(exp_time=args.exp_time, base_dir=base_dir) + + print_info("Starting analysis of polar image") + polar_process = Process(target=analyze_polar_rotation, args=(pole_fn, return_queue,)) + polar_process.start() + + # Mount Rotation + rotate_fn = mount_rotation(base_dir=base_dir) + + print_info("Starting analysis of rotation image") + rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) + rotate_process.start() + + # Wait for analyzing processes to be done + print_info("Waiting for analysis to finish") + polar_process.join() + rotate_process.join() + + while return_queue.empty() is False: + items = return_queue.get() + if items[0] == 'polar': + pole_center = (items[1], items[2]) + elif items[0] == 'rotate': + rotate_center = (items[1], items[2]) + + print_info("Plotting centers") + plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) From 7fc787545e082a1fe83fd2fb9e61259798fd0f87 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 20:48:57 +1000 Subject: [PATCH 068/149] Park the mount at end --- scripts/analyze_polar_alignment_test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 11009de4a..48423e0c8 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -221,6 +221,9 @@ def print_error(msg): rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) rotate_process.start() + print_info("Parking mount") + mount.park() + # Wait for analyzing processes to be done print_info("Waiting for analysis to finish") polar_process.join() From 4a4d9087ecaf675b677fea7ddb960ef7bce4915b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 20:50:08 +1000 Subject: [PATCH 069/149] Sanity check --- scripts/analyze_polar_alignment_test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 48423e0c8..d05bc1823 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -229,6 +229,9 @@ def print_error(msg): polar_process.join() rotate_process.join() + pole_center = None + rotate_center = None + while return_queue.empty() is False: items = return_queue.get() if items[0] == 'polar': @@ -236,5 +239,6 @@ def print_error(msg): elif items[0] == 'rotate': rotate_center = (items[1], items[2]) - print_info("Plotting centers") - plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) + if pole_center is not None and rotate_center is not None: + print_info("Plotting centers") + plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) From d1c0262a58cd77fb12900ef83a7e1f827e328b3d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 20:54:13 +1000 Subject: [PATCH 070/149] Slew to home --- scripts/analyze_polar_alignment_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index d05bc1823..411db8518 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -34,8 +34,9 @@ def polar_rotation(exp_time=300, base_dir=None, **kwargs): assert base_dir is not None, print_warning("base_dir cannot be empty") - print_info('Performing polar rotation test, slewing to home') mount.unpark() + print_info('Performing polar rotation test, slewing to home') + mount.slew_to_home() while not mount.is_home: time.sleep(2) From 744bef2fd24bc4569a32c19bbfd54b764d28e1d0 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 20:59:33 +1000 Subject: [PATCH 071/149] Say the word --- scripts/analyze_polar_alignment_test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 411db8518..73df40eea 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -171,16 +171,19 @@ def plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn=None): def print_info(msg): if verbose: + pocs.say(msg) console.color_print(msg, 'lightgreen') def print_warning(msg): if verbose: + pocs.say(msg) console.color_print(msg, 'yellow') def print_error(msg): if verbose: + pocs.say(msg) console.color_print(msg, 'red') From 9c96135e59a144aa822aec67908c91b8fceacff5 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 21:09:11 +1000 Subject: [PATCH 072/149] * Return filename * Power down --- scripts/analyze_polar_alignment_test.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 73df40eea..ac839e665 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -79,9 +79,12 @@ def polar_rotation(exp_time=300, base_dir=None, **kwargs): def mount_rotation(base_dir=None, **kwargs): print_info("Doing rotation test") + mount.slew_to_home() exp_time = 25 mount.move_direction(direction='west', seconds=11) + rotate_fn = None + # Start exposing on cameras for direction in ['east', 'west']: print_info("Rotating to {}".format(direction)) @@ -90,6 +93,8 @@ def mount_rotation(base_dir=None, **kwargs): fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) proc = cam.take_exposure(seconds=exp_time, filename=fn) procs[fn] = proc + if cam.is_primary: + rotate_fn = fn # Move mount mount.move_direction(direction=direction, seconds=21) @@ -118,8 +123,7 @@ def mount_rotation(base_dir=None, **kwargs): except AssertionError: print_warning("Can't make image for {}".format(fn)) - print_info("Done with tests, parking mount") - mount.park() + return rotate_fn def analyze_polar_rotation(pole_fn, return_queue): @@ -213,6 +217,7 @@ def print_error(msg): # Polar Rotation pole_fn = polar_rotation(exp_time=args.exp_time, base_dir=base_dir) + pole_fn = pole_fn.replace('.cr2', '.fits') print_info("Starting analysis of polar image") polar_process = Process(target=analyze_polar_rotation, args=(pole_fn, return_queue,)) @@ -220,6 +225,7 @@ def print_error(msg): # Mount Rotation rotate_fn = mount_rotation(base_dir=base_dir) + rotate_fn = pole_fn.replace('.cr2', '.fits') print_info("Starting analysis of rotation image") rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) @@ -246,3 +252,5 @@ def print_error(msg): if pole_center is not None and rotate_center is not None: print_info("Plotting centers") plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) + + pocs.power_down() From e4f7b1246844e0d93525ed7741e2cdadebbeec5c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 22:08:57 +1000 Subject: [PATCH 073/149] Remove first print statement --- scripts/analyze_polar_alignment_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index ac839e665..a0c1c8b54 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -203,7 +203,6 @@ def print_error(msg): if args.verbose: verbose = True - print_info("Setting up POCS") pocs = POCS(messaging=True) pocs.initialize() mount = pocs.observatory.mount From 49c5d8336568b4559d0d59a130ef4c2705ec91b6 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 22:45:58 +1000 Subject: [PATCH 074/149] * Wait for first process to finish before starting secon --- scripts/analyze_polar_alignment_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index a0c1c8b54..0c3a3c06c 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -226,6 +226,8 @@ def print_error(msg): rotate_fn = mount_rotation(base_dir=base_dir) rotate_fn = pole_fn.replace('.cr2', '.fits') + polar_process.join() + print_info("Starting analysis of rotation image") rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) rotate_process.start() @@ -235,7 +237,6 @@ def print_error(msg): # Wait for analyzing processes to be done print_info("Waiting for analysis to finish") - polar_process.join() rotate_process.join() pole_center = None @@ -243,6 +244,7 @@ def print_error(msg): while return_queue.empty() is False: items = return_queue.get() + print_info(items) if items[0] == 'polar': pole_center = (items[1], items[2]) elif items[0] == 'rotate': From f4db7cc90e0637e1961d52a824b89831a309f411 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 22:56:37 +1000 Subject: [PATCH 075/149] Park mount then process --- scripts/analyze_polar_alignment_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 0c3a3c06c..b8a6fb103 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -226,15 +226,15 @@ def print_error(msg): rotate_fn = mount_rotation(base_dir=base_dir) rotate_fn = pole_fn.replace('.cr2', '.fits') + print_info("Parking mount") + mount.park() + polar_process.join() print_info("Starting analysis of rotation image") rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) rotate_process.start() - print_info("Parking mount") - mount.park() - # Wait for analyzing processes to be done print_info("Waiting for analysis to finish") rotate_process.join() From 395d1e54057f05b6f76e63d36f963b17ffb506c3 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 23:01:55 +1000 Subject: [PATCH 076/149] * Skip sending message if can't --- scripts/analyze_polar_alignment_test.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index b8a6fb103..aae6a946f 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -175,20 +175,29 @@ def plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn=None): def print_info(msg): if verbose: - pocs.say(msg) console.color_print(msg, 'lightgreen') + try: + pocs.say(msg) + except Exception: + pass def print_warning(msg): if verbose: - pocs.say(msg) console.color_print(msg, 'yellow') + try: + pocs.say(msg) + except Exception: + pass def print_error(msg): if verbose: - pocs.say(msg) console.color_print(msg, 'red') + try: + pocs.say(msg) + except Exception: + pass if __name__ == '__main__': From 4e924cac6eff0dcd43bacb5ed0f6afb8bb8377f2 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 8 Apr 2017 23:16:55 +1000 Subject: [PATCH 077/149] More debug so not waiting without info --- scripts/analyze_polar_alignment_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index aae6a946f..8de3db3e5 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -238,6 +238,7 @@ def print_error(msg): print_info("Parking mount") mount.park() + print_info("Waiting for polar analysis to finish") polar_process.join() print_info("Starting analysis of rotation image") @@ -245,7 +246,7 @@ def print_error(msg): rotate_process.start() # Wait for analyzing processes to be done - print_info("Waiting for analysis to finish") + print_info("Waiting for rotate analysis to finish") rotate_process.join() pole_center = None From d97065be557471fab05b3147c0aa5c16eb7f22ba Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 13:20:44 +1000 Subject: [PATCH 078/149] * Move the actual analysis to PIAA --- scripts/analyze_polar_alignment_test.py | 62 ++----------------------- 1 file changed, 3 insertions(+), 59 deletions(-) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/analyze_polar_alignment_test.py index 8de3db3e5..440c6f230 100644 --- a/scripts/analyze_polar_alignment_test.py +++ b/scripts/analyze_polar_alignment_test.py @@ -6,24 +6,15 @@ from multiprocessing import Queue from subprocess import TimeoutExpired -from matplotlib import pyplot as plt - -from skimage.feature import canny -from skimage.transform import hough_circle -from skimage.transform import hough_circle_peaks - -from astropy.io import fits from astropy.utils import console -from astropy.visualization import SqrtStretch -from astropy.visualization.mpl_normalize import ImageNormalize - -import numpy as np from pocs import POCS from pocs.utils import current_time from pocs.utils import images as img_utils -norm = ImageNormalize(stretch=SqrtStretch()) +from piaa.utils import analyze_polar_rotation +from piaa.utils import analyze_ra_rotation +from piaa.utils import plot_center pocs = None mount = None @@ -126,53 +117,6 @@ def mount_rotation(base_dir=None, **kwargs): return rotate_fn -def analyze_polar_rotation(pole_fn, return_queue): - d1 = fits.getdata(pole_fn) - d1 = d1 / d1.max() - d2 = d1.copy() - - pole_edges = canny(d2, sigma=2.0) - - pole_hough_radii = np.arange(1000, 4500, 100) - pole_hough_res = hough_circle(pole_edges, pole_hough_radii) - pole_accums, pole_cx, pole_cy, pole_radii = hough_circle_peaks(pole_hough_res, pole_hough_radii, total_num_peaks=3) - - return_queue.put(['polar', pole_cx[-1], pole_cy[-1]]) - - -def analyze_ra_rotation(rotate_fn, return_queue): - d0 = fits.getdata(rotate_fn) - d0 = d0 / d0.max() - - # Get edges for rotation - rotate_edges = canny(d0, sigma=2.0, low_threshold=.1, high_threshold=.6) - - rotate_hough_radii = np.arange(200, 800, 50) - rotate_hough_res = hough_circle(rotate_edges, rotate_hough_radii) - rotate_accums, rotate_cx, rotate_cy, rotate_radii = \ - hough_circle_peaks(rotate_hough_res, rotate_hough_radii, total_num_peaks=3) - - return_queue.put(['rotate', rotate_cx[-1], rotate_cy[-1]]) - - -def plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn=None): - assert plot_fn is not None, print_warning("Output plot name required") - - data = fits.getdata(pole_fn) + fits.getdata(rotate_fn) - - pole_cx, pole_cy = pole_center - rotate_cx, rotate_cy = rotate_center - - fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(30, 25)) - - ax.scatter(pole_cx, pole_cy, color='r', marker='x', lw=5) - ax.scatter(rotate_cx, rotate_cy, color='r', marker='x', lw=5) - - ax.imshow(data, cmap='Greys_r', norm=norm) - ax.arrow(rotate_cx, rotate_cy, pole_cx - rotate_cx, pole_cy - rotate_cy, fc='r', ec='r') - fig.savefig(plot_fn) - - def print_info(msg): if verbose: console.color_print(msg, 'lightgreen') From 911e350ea11b3052c9c463e81cbff06c547d7070 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 13:21:24 +1000 Subject: [PATCH 079/149] Rename polar alignment file --- ...ze_polar_alignment_test.py => perform_polar_alignment_test.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{analyze_polar_alignment_test.py => perform_polar_alignment_test.py} (100%) diff --git a/scripts/analyze_polar_alignment_test.py b/scripts/perform_polar_alignment_test.py similarity index 100% rename from scripts/analyze_polar_alignment_test.py rename to scripts/perform_polar_alignment_test.py From 191ef77418f81d2e4cf54be21e371729420230e6 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 15:15:15 +1000 Subject: [PATCH 080/149] * Adding the polar alignment test to the shell * Saving changes to old script --- bin/pocs_shell | 286 +++++++++++++++--------- scripts/perform_polar_alignment_test.py | 102 ++++----- 2 files changed, 232 insertions(+), 156 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index f70df91e8..3883448bb 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -3,9 +3,8 @@ import os import readline import time -from subprocess import TimeoutExpired - from cmd import Cmd +from subprocess import TimeoutExpired from astropy import units as u from astropy.coordinates import AltAz @@ -23,6 +22,8 @@ from pocs.utils import listify from pocs.utils.database import PanMongo from pocs.utils.messaging import PanMessaging +from piaa.utils import polar_alignment + class PocsShell(Cmd): @@ -42,6 +43,18 @@ class PocsShell(Cmd): msg_pub_port = 6510 msg_sub_port = 6511 + @property + def ready(self): + if self.pocs is None: + print_warning('POCS has not been setup. Please run `setup_pocs`') + return False + + if self.pocs.observatory.mount.is_parked: + print_warning('Mount is parked. To unpark run `unpark`') + return False + + return self.pocs.is_safe() + def do_drift_align(self, *arg): """Enter the drift alignment shell """ self.do_reset_pocs() @@ -158,6 +171,79 @@ class PocsShell(Cmd): def emptyline(self): pass + def do_unpark(self, *arg): + try: + self.pocs.observatory.mount.unpark() + except Exception as e: + print_warning('Problem unparking: {}'.format(e)) + + def do_park(self, *arg): + try: + self.pocs.observatory.mount.park() + except Exception as e: + print_warning('Problem unparking: {}'.format(e)) + + def do_go_home(self, *arg): + """ Move the mount to home """ + if self.ready is False: + if self.pocs.is_weather_safe() is False: + self.do_power_down() + + return + + try: + self.pocs.observatory.mount.slew_to_home() + except Exception as e: + print_warning('Problem slewing to home: {}'.format(e)) + + def do_power_down(self, *arg): + print_info("Shutting down POCS instance, please wait") + self.pocs.power_down() + + while self.pocs.observatory.mount.is_parked is False: + print_info('.') + time.sleep(5) + + self.pocs = None + + def do_polar_alignment_test(self, *arg): + if self.ready is False: + return + + start_time = current_time(flatten=True) + + base_dir = '{}/images/drift_align/{}'.format(os.getenv('PANDIR'), start_time) + plot_fn = '{}/{}_center_overlay.png'.format(base_dir, start_time) + + mount = self.pocs.observatory.mount + + print_info("Moving to home position") + mount.slew_to_home() + + # Polar Rotation + pole_fn = polar_rotation(base_dir=base_dir) + pole_fn = pole_fn.replace('.cr2', '.fits') + + # Mount Rotation + rotate_fn = mount_rotation(base_dir=base_dir) + rotate_fn = pole_fn.replace('.cr2', '.fits') + + print_info("Moving back to home") + mount.slew_to_home() + + print_info("Solving celestial pole image") + pole_center = polar_alignment.analyze_polar_rotation(pole_fn) + + print_info("Starting analysis of rotation image") + rotate_center = polar_alignment.analyze_ra_rotation(rotate_fn) + + if pole_center is not None and rotate_center is not None: + print_info("Plotting centers") + fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) + + print_info("Plot image: {}".format(plot_fn)) + fig.savefig(plot_fn) + ################################################################################################## # Private Methods @@ -167,6 +253,103 @@ class PocsShell(Cmd): # Utility Methods ################################################################################################## +def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): + assert base_dir is not None, print_warning("base_dir cannot be empty") + + mount = pocs.observatory.mount + + print_info('Performing polar rotation test') + mount.slew_to_home() + + while not mount.is_home: + time.sleep(2) + + analyze_fn = None + + print_info('At home position, taking {} sec exposure'.format(exp_time)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/pole_{}.cr2'.format(base_dir, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + if cam.is_primary: + analyze_fn = fn + + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image(fn, title='Alignment Test - Celestial Pole', primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + + return analyze_fn + + +def mount_rotation(pocs, base_dir=None, **kwargs): + mount = pocs.observatory.mount + + print_info("Doing rotation test") + mount.slew_to_home() + exp_time = 25 + mount.move_direction(direction='west', seconds=11) + + rotate_fn = None + + # Start exposing on cameras + for direction in ['east', 'west']: + print_info("Rotating to {}".format(direction)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + if cam.is_primary: + rotate_fn = fn + + # Move mount + mount.move_direction(direction=direction, seconds=21) + + # Get exposures + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image( + fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + + return rotate_fn + class DriftShell(Cmd): @@ -274,105 +457,6 @@ class DriftShell(Cmd): print_info('Slewing to home') self.do_go_home() - def do_pole_test(self, *arg): - if not self.ready: - return - - start_time = current_time(flatten=True) - - try: - num_pics, exp_time = arg[0].split(' ') - num_pics = int(num_pics) - exp_time = float(exp_time) - except Exception: - num_pics = 5 - exp_time = 15 - - print_info('Performing pole test, slewing to home') - self.do_go_home() - while not self.pocs.observatory.mount.is_home: - time.sleep(2) - - print_info('At home position, taking {}x {}sec exposures'.format(num_pics, exp_time)) - for i in range(num_pics): - print_info('\t{} of {}'.format(i, num_pics)) - procs = dict() - for cam_name, cam in self.pocs.observatory.cameras.items(): - if not self.ready: - break - - fn = '{}/{}_pole_{}_{:02d}.cr2'.format(self.base_dir, start_time, cam_name.lower(), i) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: - continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break - - time.sleep(2) - try: - img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - - print_info("Doing rotation test") - exp_time = 25 - self.pocs.observatory.mount.move_direction(direction='west', seconds=11) - - # Start exposing on cameras - for direction in ['east', 'west']: - print_info("Rotating to {}".format(direction)) - procs = dict() - for cam_name, cam in self.pocs.observatory.cameras.items(): - fn = '{}/{}_pole_rotation_{}_{}.cr2'.format(self.base_dir, - start_time, direction, cam_name.lower()) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - - # Move mount - self.pocs.observatory.mount.move_direction(direction=direction, seconds=21) - - # Get exposures - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: - continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break - - time.sleep(2) - try: - img_utils.make_pretty_image( - fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - - print_info("Done with tests, heading back home") - self.do_go_home() - while not self.pocs.observatory.mount.is_home: - time.sleep(2) - def do_unpark(self, *arg): try: self.pocs.observatory.mount.unpark() diff --git a/scripts/perform_polar_alignment_test.py b/scripts/perform_polar_alignment_test.py index 440c6f230..f7c2f7002 100644 --- a/scripts/perform_polar_alignment_test.py +++ b/scripts/perform_polar_alignment_test.py @@ -2,8 +2,6 @@ import time from argparse import ArgumentParser -from multiprocessing import Process -from multiprocessing import Queue from subprocess import TimeoutExpired from astropy.utils import console @@ -12,9 +10,9 @@ from pocs.utils import current_time from pocs.utils import images as img_utils -from piaa.utils import analyze_polar_rotation -from piaa.utils import analyze_ra_rotation -from piaa.utils import plot_center +from piaa.utils.polar_alignment import analyze_polar_rotation +from piaa.utils.polar_alignment import analyze_ra_rotation +from piaa.utils.polar_alignment import plot_center pocs = None mount = None @@ -22,11 +20,10 @@ verbose = False -def polar_rotation(exp_time=300, base_dir=None, **kwargs): +def polar_rotation(exp_time=30, base_dir=None, **kwargs): assert base_dir is not None, print_warning("base_dir cannot be empty") - mount.unpark() - print_info('Performing polar rotation test, slewing to home') + print_info('Performing polar rotation test') mount.slew_to_home() while not mount.is_home: @@ -60,7 +57,7 @@ def polar_rotation(exp_time=300, base_dir=None, **kwargs): time.sleep(2) try: - img_utils.make_pretty_image(fn, title='Alignment Test - Polaris', primary=True) + img_utils.make_pretty_image(fn, title='Alignment Test - Celestial Pole', primary=True) img_utils.cr2_to_fits(fn, remove_cr2=True) except AssertionError: print_warning("Can't make image for {}".format(fn)) @@ -144,68 +141,63 @@ def print_error(msg): pass -if __name__ == '__main__': - parser = ArgumentParser(description='Perform a polar alignment test') - parser.add_argument('--exp-time', default=300, help='Exposure time for polar rotation') - parser.add_argument('--base-dir', default='{}/images/drift_align'.format(os.getenv('PANDIR')), - help='Directory to store images') - parser.add_argument('--verbose', action="store_true", default='False', help='Verbose') - - args = parser.parse_args() - - if args.verbose: - verbose = True - - pocs = POCS(messaging=True) - pocs.initialize() - mount = pocs.observatory.mount - +def perform_tests(base_dir): start_time = current_time(flatten=True) - return_queue = Queue() - - base_dir = '{}/{}/'.format(args.base_dir, start_time) + base_dir = '{}/{}/'.format(base_dir, start_time) plot_fn = '{}/{}_center_overlay.png'.format(base_dir, start_time) + print_info("Moving to home position") + mount.slew_to_home() + # Polar Rotation - pole_fn = polar_rotation(exp_time=args.exp_time, base_dir=base_dir) + pole_fn = polar_rotation(base_dir=base_dir) pole_fn = pole_fn.replace('.cr2', '.fits') - print_info("Starting analysis of polar image") - polar_process = Process(target=analyze_polar_rotation, args=(pole_fn, return_queue,)) - polar_process.start() - # Mount Rotation rotate_fn = mount_rotation(base_dir=base_dir) rotate_fn = pole_fn.replace('.cr2', '.fits') - print_info("Parking mount") - mount.park() + print_info("Moving back to home") + mount.slew_to_home() - print_info("Waiting for polar analysis to finish") - polar_process.join() + print_info("Solving celestial pole image") + pole_center = analyze_polar_rotation(pole_fn) print_info("Starting analysis of rotation image") - rotate_process = Process(target=analyze_ra_rotation, args=(rotate_fn, return_queue,)) - rotate_process.start() + rotate_center = analyze_ra_rotation(rotate_fn) + + if pole_center is not None and rotate_center is not None: + print_info("Plotting centers") + fig = plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) + print_info("Plot image: {}".format(plot_fn)) + fig.savefig(plot_fn) - # Wait for analyzing processes to be done - print_info("Waiting for rotate analysis to finish") - rotate_process.join() - pole_center = None - rotate_center = None +if __name__ == '__main__': + parser = ArgumentParser(description='Perform a polar alignment test') + parser.add_argument('--base-dir', default='{}/images/drift_align'.format(os.getenv('PANDIR')), + help='Directory to store images') + parser.add_argument('--verbose', action="store_true", default='False', help='Verbose') - while return_queue.empty() is False: - items = return_queue.get() - print_info(items) - if items[0] == 'polar': - pole_center = (items[1], items[2]) - elif items[0] == 'rotate': - rotate_center = (items[1], items[2]) + args = parser.parse_args() - if pole_center is not None and rotate_center is not None: - print_info("Plotting centers") - plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) + if args.verbose: + verbose = True + + pocs = POCS(messaging=True) + pocs.initialize() + mount = pocs.observatory.mount + + mount.unpark() + + while True: + perform_tests(args.base_dir) + + pocs.sleep() + + if mount.is_parked: + break - pocs.power_down() + if pocs.connected: + pocs.power_down() From 885273e613f662a17790bcb73687a523ca53937d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 15:15:30 +1000 Subject: [PATCH 081/149] Removing script --- scripts/perform_polar_alignment_test.py | 203 ------------------------ 1 file changed, 203 deletions(-) delete mode 100644 scripts/perform_polar_alignment_test.py diff --git a/scripts/perform_polar_alignment_test.py b/scripts/perform_polar_alignment_test.py deleted file mode 100644 index f7c2f7002..000000000 --- a/scripts/perform_polar_alignment_test.py +++ /dev/null @@ -1,203 +0,0 @@ -import os -import time - -from argparse import ArgumentParser -from subprocess import TimeoutExpired - -from astropy.utils import console - -from pocs import POCS -from pocs.utils import current_time -from pocs.utils import images as img_utils - -from piaa.utils.polar_alignment import analyze_polar_rotation -from piaa.utils.polar_alignment import analyze_ra_rotation -from piaa.utils.polar_alignment import plot_center - -pocs = None -mount = None - -verbose = False - - -def polar_rotation(exp_time=30, base_dir=None, **kwargs): - assert base_dir is not None, print_warning("base_dir cannot be empty") - - print_info('Performing polar rotation test') - mount.slew_to_home() - - while not mount.is_home: - time.sleep(2) - - analyze_fn = None - - print_info('At home position, taking {} sec exposure'.format(exp_time)) - procs = dict() - for cam_name, cam in pocs.observatory.cameras.items(): - fn = '{}/pole_{}.cr2'.format(base_dir, cam_name.lower()) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - if cam.is_primary: - analyze_fn = fn - - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: - continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break - - time.sleep(2) - try: - img_utils.make_pretty_image(fn, title='Alignment Test - Celestial Pole', primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - - return analyze_fn - - -def mount_rotation(base_dir=None, **kwargs): - print_info("Doing rotation test") - mount.slew_to_home() - exp_time = 25 - mount.move_direction(direction='west', seconds=11) - - rotate_fn = None - - # Start exposing on cameras - for direction in ['east', 'west']: - print_info("Rotating to {}".format(direction)) - procs = dict() - for cam_name, cam in pocs.observatory.cameras.items(): - fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - if cam.is_primary: - rotate_fn = fn - - # Move mount - mount.move_direction(direction=direction, seconds=21) - - # Get exposures - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: - continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break - - time.sleep(2) - try: - img_utils.make_pretty_image( - fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - - return rotate_fn - - -def print_info(msg): - if verbose: - console.color_print(msg, 'lightgreen') - try: - pocs.say(msg) - except Exception: - pass - - -def print_warning(msg): - if verbose: - console.color_print(msg, 'yellow') - try: - pocs.say(msg) - except Exception: - pass - - -def print_error(msg): - if verbose: - console.color_print(msg, 'red') - try: - pocs.say(msg) - except Exception: - pass - - -def perform_tests(base_dir): - start_time = current_time(flatten=True) - - base_dir = '{}/{}/'.format(base_dir, start_time) - plot_fn = '{}/{}_center_overlay.png'.format(base_dir, start_time) - - print_info("Moving to home position") - mount.slew_to_home() - - # Polar Rotation - pole_fn = polar_rotation(base_dir=base_dir) - pole_fn = pole_fn.replace('.cr2', '.fits') - - # Mount Rotation - rotate_fn = mount_rotation(base_dir=base_dir) - rotate_fn = pole_fn.replace('.cr2', '.fits') - - print_info("Moving back to home") - mount.slew_to_home() - - print_info("Solving celestial pole image") - pole_center = analyze_polar_rotation(pole_fn) - - print_info("Starting analysis of rotation image") - rotate_center = analyze_ra_rotation(rotate_fn) - - if pole_center is not None and rotate_center is not None: - print_info("Plotting centers") - fig = plot_center(pole_fn, rotate_fn, pole_center, rotate_center, plot_fn) - print_info("Plot image: {}".format(plot_fn)) - fig.savefig(plot_fn) - - -if __name__ == '__main__': - parser = ArgumentParser(description='Perform a polar alignment test') - parser.add_argument('--base-dir', default='{}/images/drift_align'.format(os.getenv('PANDIR')), - help='Directory to store images') - parser.add_argument('--verbose', action="store_true", default='False', help='Verbose') - - args = parser.parse_args() - - if args.verbose: - verbose = True - - pocs = POCS(messaging=True) - pocs.initialize() - mount = pocs.observatory.mount - - mount.unpark() - - while True: - perform_tests(args.base_dir) - - pocs.sleep() - - if mount.is_parked: - break - - if pocs.connected: - pocs.power_down() From 6bfd6283f7a2a463194c9831b1ccad513edaadb4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 15:17:00 +1000 Subject: [PATCH 082/149] * Start POCS with messaging --- bin/pocs_shell | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 3883448bb..3eea20580 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -105,7 +105,7 @@ class PocsShell(Cmd): simulator = [] try: - self.pocs = POCS(simulator=simulator) + self.pocs = POCS(simulator=simulator, messaging=True) self.pocs.initialize() except error.PanError: pass @@ -123,8 +123,6 @@ class PocsShell(Cmd): *arg {str} -- Can pass arguments through to `do_connect` """ if self.pocs is not None: - self.pocs.has_messaging = True - if self.msg_subscriber is None: self.do_start_messaging() From 2f107977c43041cae65806906c849f5c7a90e708 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 15:33:53 +1000 Subject: [PATCH 083/149] Shell * Add web listen mode --- bin/pocs_shell | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 3eea20580..4afd62a0a 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -2,6 +2,7 @@ import os import readline import time +import zmq from cmd import Cmd from subprocess import TimeoutExpired @@ -40,6 +41,7 @@ class PocsShell(Cmd): cmd_publisher = None cmd_pub_port = 6500 + cmd_sub_port = 6501 msg_pub_port = 6510 msg_sub_port = 6511 @@ -82,18 +84,27 @@ class PocsShell(Cmd): # Send commands to POCS via this publisher try: self.cmd_publisher = PanMessaging.create_publisher(self.cmd_pub_port) + print_info("Command publisher started on port {}".format(self.cmd_pub_port)) except Exception as e: print_warning("Can't start command publisher: {}".format(e)) + try: + self.cmd_subscriber = PanMessaging.create_subscriber(self.cmd_sub_port) + print_info("Command subscriber started on port {}".format(self.cmd_sub_port)) + except Exception as e: + print_warning("Can't start command subscriber: {}".format(e)) + # Receive messages from POCS via this subscriber try: self.msg_subscriber = PanMessaging.create_subscriber(self.msg_sub_port) + print_info("Message subscriber started on port {}".format(self.msg_sub_port)) except Exception as e: print_warning("Can't start message subscriber: {}".format(e)) # Send messages to PAWS try: self.msg_publisher = PanMessaging.create_publisher(self.msg_pub_port) + print_info("Message publisher started on port {}".format(self.msg_pub_port)) except Exception as e: print_warning("Can't start message publisher: {}".format(e)) @@ -161,7 +172,8 @@ class PocsShell(Cmd): def do_exit(self, *arg): """ Exits PanShell """ - self.do_reset_pocs() + if self.pocs is not None: + self.do_power_down() print_info("Bye! Thanks!") return True @@ -242,6 +254,29 @@ class PocsShell(Cmd): print_info("Plot image: {}".format(plot_fn)) fig.savefig(plot_fn) + def do_web_listen(self, *arg): + """ Goes into a loop listening for commands from PAWS """ + poller = zmq.Poller() + poller.register(self.cmd_subscriber.socket, zmq.POLLIN) + + try: + while True: + # Poll for messages + sockets = dict(poller.poll(500)) # 500 ms timeout + + if self.cmd_subscriber.socket in sockets and sockets[self.cmd_subscriber.socket] == zmq.POLLIN: + + msg_type, msg_obj = self.cmd_subscriber.receive_message(flags=zmq.NOBLOCK) + + # Put the message in a queue to be processed + if msg_type == 'PAWS-CMD': + if msg_obj['command'] == 'polar_alignment': + print_info("Do polar alignment here!") + + time.sleep(1) + except KeyboardInterrupt: + pass + ################################################################################################## # Private Methods From 8857e346a4f43a0c8f6de7b49d47102f7f293ba5 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 15:43:10 +1000 Subject: [PATCH 084/149] Listen for command better --- bin/pocs_shell | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 4afd62a0a..d9c0737c6 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -270,8 +270,11 @@ class PocsShell(Cmd): # Put the message in a queue to be processed if msg_type == 'PAWS-CMD': - if msg_obj['command'] == 'polar_alignment': - print_info("Do polar alignment here!") + try: + if msg_obj['command'] == 'polar_alignment': + print_info("Do polar alignment here!") + except KeyError: + pass time.sleep(1) except KeyboardInterrupt: From dc06b69e6e8c1561c06873d5f2cb6e8ee95b66be Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 16:27:23 +1000 Subject: [PATCH 085/149] * Show print output * Automatically start messaging --- bin/pocs_shell | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index d9c0737c6..ff1ce1978 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -256,6 +256,10 @@ class PocsShell(Cmd): def do_web_listen(self, *arg): """ Goes into a loop listening for commands from PAWS """ + + if self.cmd_subscriber is None: + self.do_start_messaging() + poller = zmq.Poller() poller.register(self.cmd_subscriber.socket, zmq.POLLIN) @@ -267,6 +271,7 @@ class PocsShell(Cmd): if self.cmd_subscriber.socket in sockets and sockets[self.cmd_subscriber.socket] == zmq.POLLIN: msg_type, msg_obj = self.cmd_subscriber.receive_message(flags=zmq.NOBLOCK) + print_info("{} {}".format(msg_type, msg_obj)) # Put the message in a queue to be processed if msg_type == 'PAWS-CMD': From 9b0b55587c4df20ea9bca18bc2dc619a10385bd9 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 16:32:10 +1000 Subject: [PATCH 086/149] * Use built-in message mechanism --- bin/pocs_shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index ff1ce1978..f436b1411 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -257,7 +257,7 @@ class PocsShell(Cmd): def do_web_listen(self, *arg): """ Goes into a loop listening for commands from PAWS """ - if self.cmd_subscriber is None: + if not hasattr(self, 'cmd_subscriber'): self.do_start_messaging() poller = zmq.Poller() @@ -276,7 +276,7 @@ class PocsShell(Cmd): # Put the message in a queue to be processed if msg_type == 'PAWS-CMD': try: - if msg_obj['command'] == 'polar_alignment': + if msg_obj['message'] == 'polar_alignment': print_info("Do polar alignment here!") except KeyError: pass From 5a4802864874d359ff84b0281f593749a236af5f Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 16:37:13 +1000 Subject: [PATCH 087/149] * Add command lookup and actually do commands --- bin/pocs_shell | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index f436b1411..b7a291698 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -263,6 +263,13 @@ class PocsShell(Cmd): poller = zmq.Poller() poller.register(self.cmd_subscriber.socket, zmq.POLLIN) + command_lookup = { + 'polar_alignment': self.do_polar_alignment_test, + 'park': self.do_park, + 'unpark': self.do_unpark, + 'home': self.do_go_home, + } + try: while True: # Poll for messages @@ -276,10 +283,13 @@ class PocsShell(Cmd): # Put the message in a queue to be processed if msg_type == 'PAWS-CMD': try: - if msg_obj['message'] == 'polar_alignment': - print_info("Do polar alignment here!") + print_info("Command received: {}".format(msg_obj['message'])) + cmd = command_lookup[msg_obj['message']] + cmd() except KeyError: pass + except Exception as e: + print_warning("Can't perform command: {}".format(e)) time.sleep(1) except KeyboardInterrupt: From 12896a904cacfc218c2e60d0d3f4fb71b32073bd Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 16:44:14 +1000 Subject: [PATCH 088/149] * Pass `pocs` to sub commands --- bin/pocs_shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index b7a291698..d212c0735 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -231,11 +231,11 @@ class PocsShell(Cmd): mount.slew_to_home() # Polar Rotation - pole_fn = polar_rotation(base_dir=base_dir) + pole_fn = polar_rotation(self.pocs, base_dir=base_dir) pole_fn = pole_fn.replace('.cr2', '.fits') # Mount Rotation - rotate_fn = mount_rotation(base_dir=base_dir) + rotate_fn = mount_rotation(self.pocs, base_dir=base_dir) rotate_fn = pole_fn.replace('.cr2', '.fits') print_info("Moving back to home") From 2cb257b6023f7b81e1ffb5a082e400aefa8d858c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 16:59:51 +1000 Subject: [PATCH 089/149] Link polar plot to website --- bin/pocs_shell | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index d212c0735..8244e6537 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -223,7 +223,7 @@ class PocsShell(Cmd): start_time = current_time(flatten=True) base_dir = '{}/images/drift_align/{}'.format(os.getenv('PANDIR'), start_time) - plot_fn = '{}/{}_center_overlay.png'.format(base_dir, start_time) + plot_fn = '{}/{}_center_overlay.jpg'.format(base_dir, start_time) mount = self.pocs.observatory.mount @@ -252,8 +252,15 @@ class PocsShell(Cmd): fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) print_info("Plot image: {}".format(plot_fn)) + fig.tight_layout() fig.savefig(plot_fn) + try: + os.unlink('/var/panoptes/images/latest.jpg') + os.symlink(plot_fn, '/var/panoptes/images/latest.jpg') + except Exception: + print_warning("Can't link latest image") + def do_web_listen(self, *arg): """ Goes into a loop listening for commands from PAWS """ From 61faf7f49ceb2888248041f54dc6e83859bab540 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 17:14:04 +1000 Subject: [PATCH 090/149] * Show which images are being used --- bin/pocs_shell | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index 8244e6537..f565158c4 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -249,6 +249,8 @@ class PocsShell(Cmd): if pole_center is not None and rotate_center is not None: print_info("Plotting centers") + print_info("Pole: {} {}".format(pole_center, pole_fn)) + print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) print_info("Plot image: {}".format(plot_fn)) From 0883a075ac3664d37bda54dd0af93a7162b1a858 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 17:25:34 +1000 Subject: [PATCH 091/149] * Use the correct image --- bin/pocs_shell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index f565158c4..a86cb89e1 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -236,7 +236,7 @@ class PocsShell(Cmd): # Mount Rotation rotate_fn = mount_rotation(self.pocs, base_dir=base_dir) - rotate_fn = pole_fn.replace('.cr2', '.fits') + rotate_fn = rotate_fn.replace('.cr2', '.fits') print_info("Moving back to home") mount.slew_to_home() From 1ce710a4a41e8d0de3be8e4b3d6a72502d4ef943 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 17:55:01 +1000 Subject: [PATCH 092/149] Show say output --- bin/pocs_shell | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index a86cb89e1..ab6bac51e 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -228,6 +228,7 @@ class PocsShell(Cmd): mount = self.pocs.observatory.mount print_info("Moving to home position") + self.pocs.say("Moving to home position") mount.slew_to_home() # Polar Rotation @@ -239,18 +240,27 @@ class PocsShell(Cmd): rotate_fn = rotate_fn.replace('.cr2', '.fits') print_info("Moving back to home") + self.pocs.say("Moving back to home") mount.slew_to_home() print_info("Solving celestial pole image") + self.pocs.say("Solving celestial pole image") pole_center = polar_alignment.analyze_polar_rotation(pole_fn) print_info("Starting analysis of rotation image") + self.pocs.say("Starting analysis of rotation image") rotate_center = polar_alignment.analyze_ra_rotation(rotate_fn) if pole_center is not None and rotate_center is not None: print_info("Plotting centers") + self.pocs.say("Plotting centers") + print_info("Pole: {} {}".format(pole_center, pole_fn)) + self.pocs.say("Pole: {} {}".format(pole_center, pole_fn)) + print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) + self.pocs.say("Rotate: {} {}".format(rotate_center, rotate_fn)) + fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) print_info("Plot image: {}".format(plot_fn)) @@ -263,6 +273,9 @@ class PocsShell(Cmd): except Exception: print_warning("Can't link latest image") + print_info("Done with polar alignment test") + self.pocs.say("Done with polar alignment test") + def do_web_listen(self, *arg): """ Goes into a loop listening for commands from PAWS """ @@ -319,6 +332,7 @@ def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): mount = pocs.observatory.mount print_info('Performing polar rotation test') + pocs.say('Performing polar rotation test') mount.slew_to_home() while not mount.is_home: @@ -327,6 +341,7 @@ def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): analyze_fn = None print_info('At home position, taking {} sec exposure'.format(exp_time)) + pocs.say('At home position, taking {} sec exposure'.format(exp_time)) procs = dict() for cam_name, cam in pocs.observatory.cameras.items(): fn = '{}/pole_{}.cr2'.format(base_dir, cam_name.lower()) @@ -356,6 +371,7 @@ def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): img_utils.cr2_to_fits(fn, remove_cr2=True) except AssertionError: print_warning("Can't make image for {}".format(fn)) + pocs.say("Can't make image for {}".format(fn)) return analyze_fn @@ -364,6 +380,7 @@ def mount_rotation(pocs, base_dir=None, **kwargs): mount = pocs.observatory.mount print_info("Doing rotation test") + pocs.say("Doing rotation test") mount.slew_to_home() exp_time = 25 mount.move_direction(direction='west', seconds=11) @@ -373,6 +390,7 @@ def mount_rotation(pocs, base_dir=None, **kwargs): # Start exposing on cameras for direction in ['east', 'west']: print_info("Rotating to {}".format(direction)) + pocs.say("Rotating to {}".format(direction)) procs = dict() for cam_name, cam in pocs.observatory.cameras.items(): fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) @@ -392,6 +410,7 @@ def mount_rotation(pocs, base_dir=None, **kwargs): continue except KeyboardInterrupt: print_warning('Pole test interrupted') + pocs.say('Pole test interrupted') proc.kill() outs, errs = proc.communicate() break @@ -407,6 +426,7 @@ def mount_rotation(pocs, base_dir=None, **kwargs): img_utils.cr2_to_fits(fn, remove_cr2=True) except AssertionError: print_warning("Can't make image for {}".format(fn)) + pocs.say("Can't make image for {}".format(fn)) return rotate_fn From 336e6cd66869bafe71d92a86a8e5fd29e3bfc6bf Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:06:15 +1000 Subject: [PATCH 093/149] Better output --- bin/pocs_shell | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index ab6bac51e..1a69e9845 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -246,6 +246,7 @@ class PocsShell(Cmd): print_info("Solving celestial pole image") self.pocs.say("Solving celestial pole image") pole_center = polar_alignment.analyze_polar_rotation(pole_fn) + pole_center = (pole_center[0][0], pole_center[1][0]) print_info("Starting analysis of rotation image") self.pocs.say("Starting analysis of rotation image") @@ -256,10 +257,10 @@ class PocsShell(Cmd): self.pocs.say("Plotting centers") print_info("Pole: {} {}".format(pole_center, pole_fn)) - self.pocs.say("Pole: {} {}".format(pole_center, pole_fn)) + self.pocs.say("Pole: {}".format(pole_center)) print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) - self.pocs.say("Rotate: {} {}".format(rotate_center, rotate_fn)) + self.pocs.say("Rotate: {}".format(rotate_center[0])) fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) From b5e8d4cf46d3caf8c8b2960ee6134631e5742aa6 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:14:43 +1000 Subject: [PATCH 094/149] * Better formatting of center values --- bin/pocs_shell | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 1a69e9845..c3996a941 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -246,7 +246,7 @@ class PocsShell(Cmd): print_info("Solving celestial pole image") self.pocs.say("Solving celestial pole image") pole_center = polar_alignment.analyze_polar_rotation(pole_fn) - pole_center = (pole_center[0][0], pole_center[1][0]) + pole_center = (float(pole_center[0]), float(pole_center[1])) print_info("Starting analysis of rotation image") self.pocs.say("Starting analysis of rotation image") @@ -257,10 +257,10 @@ class PocsShell(Cmd): self.pocs.say("Plotting centers") print_info("Pole: {} {}".format(pole_center, pole_fn)) - self.pocs.say("Pole: {}".format(pole_center)) + self.pocs.say("Pole: {:0.2f} {:0.2f}".format(pole_center[0], pole_center[1])) print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) - self.pocs.say("Rotate: {}".format(rotate_center[0])) + self.pocs.say("Rotate: {:0.2f} {:0.2f}".format(rotate_center[0], rotate_center[1])) fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) From 92e149bcf48a61b8ab31d0eb0fa1e5c30fcb886a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:19:32 +1000 Subject: [PATCH 095/149] Don't barf if no image --- bin/pocs_shell | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index c3996a941..161926d6a 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -270,6 +270,9 @@ class PocsShell(Cmd): try: os.unlink('/var/panoptes/images/latest.jpg') + except Exception: + pass + try: os.symlink(plot_fn, '/var/panoptes/images/latest.jpg') except Exception: print_warning("Can't link latest image") From 82cc026c5b02db179e3f0bcd18499e492656b6ad Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:21:01 +1000 Subject: [PATCH 096/149] More formatting --- bin/pocs_shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 161926d6a..b61daade6 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -257,10 +257,10 @@ class PocsShell(Cmd): self.pocs.say("Plotting centers") print_info("Pole: {} {}".format(pole_center, pole_fn)) - self.pocs.say("Pole: {:0.2f} {:0.2f}".format(pole_center[0], pole_center[1])) + self.pocs.say("Pole : {:0.2f} x {:0.2f}".format(pole_center[0], pole_center[1])) print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) - self.pocs.say("Rotate: {:0.2f} {:0.2f}".format(rotate_center[0], rotate_center[1])) + self.pocs.say("Rotate: {:0.2f} x {:0.2f}".format(rotate_center[0], rotate_center[1])) fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) From 160e4abc7df0e4a6f4c64ede589f021b59efe939 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:53:50 +1000 Subject: [PATCH 097/149] * Output message when parked --- bin/pocs_shell | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index b61daade6..181c85513 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -190,6 +190,7 @@ class PocsShell(Cmd): def do_park(self, *arg): try: self.pocs.observatory.mount.park() + self.pocs.say("Mount parked") except Exception as e: print_warning('Problem unparking: {}'.format(e)) From 2f0ec6456d3fb21e99ef39db153bbaded2ca5b0b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 18:54:03 +1000 Subject: [PATCH 098/149] More messages --- bin/pocs_shell | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index 181c85513..3a72c7b38 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -184,6 +184,7 @@ class PocsShell(Cmd): def do_unpark(self, *arg): try: self.pocs.observatory.mount.unpark() + self.pocs.say("Unparking mount") except Exception as e: print_warning('Problem unparking: {}'.format(e)) From 7009ae1b8e1c1a0b754b602ba4ed942e25399341 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 19:11:12 +1000 Subject: [PATCH 099/149] * Message when listening --- bin/pocs_shell | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index 3a72c7b38..8a9e3ecd9 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -288,6 +288,8 @@ class PocsShell(Cmd): if not hasattr(self, 'cmd_subscriber'): self.do_start_messaging() + self.pocs.say("Now listening for commands from PAWS") + poller = zmq.Poller() poller.register(self.cmd_subscriber.socket, zmq.POLLIN) @@ -321,6 +323,7 @@ class PocsShell(Cmd): time.sleep(1) except KeyboardInterrupt: + self.pocs.say("No longer listening to PAWS") pass From 35c1e7bb3255d82ed6b2cfcbddbaa5fe51b9e178 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 19:27:36 +1000 Subject: [PATCH 100/149] * Dont' actually adjust mount but report values --- pocs/observatory.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 6bea82f9b..4adb853e1 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -340,12 +340,12 @@ def update_tracking(self): ra_direction = 'west' self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) - if dec_ms.value >= 1.: - self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + # if dec_ms.value >= 1.: + # self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) self.logger.info("Adjusting mount ra: {} {} {}".format(ra_direction, ra_ms, ra_offset)) - if ra_ms.value >= 1.: - self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) + # if ra_ms.value >= 1.: + # self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) def get_standard_headers(self, observation=None): """Get a set of standard headers From c90aafb7473087ec23c0db37bd70eaadf11a5e41 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 19:38:37 +1000 Subject: [PATCH 101/149] * Try to sort export but proceed if not --- pocs/utils/database.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pocs/utils/database.py b/pocs/utils/database.py index 8adfb6fc1..bccb982f5 100644 --- a/pocs/utils/database.py +++ b/pocs/utils/database.py @@ -160,7 +160,11 @@ def export(self, out_file = '{}{}_{}.json'.format(backup_dir, date_str.replace('-', ''), collection) col = getattr(self, collection) - entries = [x for x in col.find({'date': {'$gt': start, '$lt': end}}).sort([('date', pymongo.ASCENDING)])] + try: + entries = [x for x in col.find({'date': {'$gt': start, '$lt': end}} + ).sort([('date', pymongo.ASCENDING)])] + except pymongo.errors.OperationFailure: + entries = [x for x in col.find({'date': {'$gt': start, '$lt': end}})] if len(entries): console.color_print("\t\t{} records exported".format(len(entries)), 'yellow') From c8170b2bb369111aa7d706e7365897361e1776b4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 20:05:05 +1000 Subject: [PATCH 102/149] Only try tracking update if we have info --- pocs/observatory.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 4adb853e1..5f9ad9603 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -325,27 +325,29 @@ def update_tracking(self): Uses the `rate_adjustment` key from the `self.current_offset_info` """ - dec_offset = self.current_offset_info.delta_dec - dec_ms = self.mount.get_ms_offset(dec_offset) - if dec_offset >= 0: - dec_direction = 'north' - else: - dec_direction = 'south' + if self.current_offset_info is not None: - ra_offset = self.current_offset_info.delta_ra - ra_ms = self.mount.get_ms_offset(ra_offset) - if ra_offset >= 0: - ra_direction = 'east' - else: - ra_direction = 'west' + dec_offset = self.current_offset_info.delta_dec + dec_ms = self.mount.get_ms_offset(dec_offset) + if dec_offset >= 0: + dec_direction = 'north' + else: + dec_direction = 'south' + + ra_offset = self.current_offset_info.delta_ra + ra_ms = self.mount.get_ms_offset(ra_offset) + if ra_offset >= 0: + ra_direction = 'east' + else: + ra_direction = 'west' - self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) - # if dec_ms.value >= 1.: - # self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) + # if dec_ms.value >= 1.: + # self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) - self.logger.info("Adjusting mount ra: {} {} {}".format(ra_direction, ra_ms, ra_offset)) - # if ra_ms.value >= 1.: - # self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) + self.logger.info("Adjusting mount ra: {} {} {}".format(ra_direction, ra_ms, ra_offset)) + # if ra_ms.value >= 1.: + # self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) def get_standard_headers(self, observation=None): """Get a set of standard headers From e635ef1221694895a7c9493c346c005c513c255a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 20:06:02 +1000 Subject: [PATCH 103/149] * Don't show warning if now WCS, just debug --- pocs/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/images.py b/pocs/images.py index 5269e7d22..76d1c6d23 100644 --- a/pocs/images.py +++ b/pocs/images.py @@ -99,7 +99,7 @@ def wcs_file(self, filename): self.wcs = w self._wcs_file = filename except Exception: - self.logger.warn("Can't get WCS from FITS file (try solve_field)") + self.logger.debug("Can't get WCS from FITS file (try solve_field)") @property def pointing_error(self): From b928e8f65e5637296fe9d757ea17bcd7cc987c4e Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 20:16:37 +1000 Subject: [PATCH 104/149] Try to adjust the dec but don't let it get out of hand --- pocs/observatory.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 5f9ad9603..92445da73 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -341,11 +341,11 @@ def update_tracking(self): else: ra_direction = 'west' - self.logger.info("Adjusting mount dec: {} {} {}".format(dec_direction, dec_ms, dec_offset)) - # if dec_ms.value >= 1.: - # self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms, dec_offset)) + if dec_ms.value >= 1. and dec_ms.value <= 10000: + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) - self.logger.info("Adjusting mount ra: {} {} {}".format(ra_direction, ra_ms, ra_offset)) + self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms, ra_offset)) # if ra_ms.value >= 1.: # self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) From 70cc107626863ccf0112c0555fced073d5c57ac2 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 20:30:06 +1000 Subject: [PATCH 105/149] * Don't set offset info to empty dict --- pocs/observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 92445da73..b4ba8188a 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -276,7 +276,7 @@ def analyze_recent(self): dict: Offset information """ # Clear the offset info - self.current_offset_info = dict() + self.current_offset_info = None ref_image_id, ref_image_path = self.current_observation.first_exposure From 1b9e9447a530261697d9fdce3dfadcfb52ed305e Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 20:41:51 +1000 Subject: [PATCH 106/149] Adjust dec slightly more --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index b4ba8188a..4244e7423 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -341,9 +341,9 @@ def update_tracking(self): else: ra_direction = 'west' - self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms, dec_offset)) + self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms * 1.5, dec_offset)) if dec_ms.value >= 1. and dec_ms.value <= 10000: - self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value)) + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value * 1.5)) self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms, ra_offset)) # if ra_ms.value >= 1.: From 2d3c147d1faa6788f566dbe9cac90985e4d3f446 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 21:30:32 +1000 Subject: [PATCH 107/149] Test RA drift --- pocs/observatory.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 4244e7423..a8dfaba48 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -345,9 +345,9 @@ def update_tracking(self): if dec_ms.value >= 1. and dec_ms.value <= 10000: self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value * 1.5)) - self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms, ra_offset)) - # if ra_ms.value >= 1.: - # self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value)) + self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms * 1.5, ra_offset)) + if ra_ms.value >= 1. and ra_ms.value <= 10000: + self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value * 1.5)) def get_standard_headers(self, observation=None): """Get a set of standard headers From b1df292cac6ae00fa6662b2d903dd76c3c02d149 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 22:21:39 +1000 Subject: [PATCH 108/149] * Use absolute values --- pocs/observatory.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index a8dfaba48..9b683e58d 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -342,12 +342,12 @@ def update_tracking(self): ra_direction = 'west' self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms * 1.5, dec_offset)) - if dec_ms.value >= 1. and dec_ms.value <= 10000: - self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_ms.value * 1.5)) + if abs(dec_ms.value) >= 1. and abs(dec_ms.value) <= 10000: + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(abs(dec_ms.value) * 1.5)) self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms * 1.5, ra_offset)) - if ra_ms.value >= 1. and ra_ms.value <= 10000: - self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_ms.value * 1.5)) + if abs(ra_ms.value) >= 1. and abs(ra_ms.value) <= 10000: + self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(abs(ra_ms.value) * 1.5)) def get_standard_headers(self, observation=None): """Get a set of standard headers From 8b3e1a5176a06d09ebdcc9c8d84e22cc16cc38c2 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 22:46:34 +1000 Subject: [PATCH 109/149] Switch RA direction --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 9b683e58d..d918d2e3d 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -337,9 +337,9 @@ def update_tracking(self): ra_offset = self.current_offset_info.delta_ra ra_ms = self.mount.get_ms_offset(ra_offset) if ra_offset >= 0: - ra_direction = 'east' - else: ra_direction = 'west' + else: + ra_direction = 'east' self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms * 1.5, dec_offset)) if abs(dec_ms.value) >= 1. and abs(dec_ms.value) <= 10000: From 4b7f39270be0fdc283e2a530885dbc3aec3ac21c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 9 Apr 2017 23:18:24 +1000 Subject: [PATCH 110/149] Don't get stuck in the same state --- pocs/state/machine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pocs/state/machine.py b/pocs/state/machine.py index f3ef6d3ab..72002f486 100644 --- a/pocs/state/machine.py +++ b/pocs/state/machine.py @@ -140,6 +140,8 @@ def run(self, exit_when_done=False, run_once=False): else: _loop_iteration = _loop_iteration + 1 self.sleep(with_status=False) + else: + _loop_iteration = 0 if self.state == 'sleeping' and self.run_once: self.stop_states() From f7df7772993eb0df7ccc3998a499d68737b1ad52 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 08:09:14 +1000 Subject: [PATCH 111/149] Adding more targets --- resources/targets/simple.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index b10011369..842103eb9 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -43,6 +43,10 @@ name: Wasp 33 position: 02h26m51.0582s +37d33m01.733s priority: 100 +- + name: Wasp 43 + position: 10h19m38.008s -09d48m22.59s + priority: 100 - name: Wasp 36 position: 08h46m19.30s -08d01m36.7s From 7d6eb7f84c74f502ebcbd27e35dfc941e92c02df Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 08:39:44 +1000 Subject: [PATCH 112/149] Adding more targets --- resources/targets/simple.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/targets/simple.yaml b/resources/targets/simple.yaml index 842103eb9..573b2ffa5 100644 --- a/resources/targets/simple.yaml +++ b/resources/targets/simple.yaml @@ -83,6 +83,10 @@ name: HAT-P-1 position: 22h57m47.0s +38d40m30.0s priority: 100 +- + name: HAT-P-12 + position: 13h57m33.48s +43d29m36.7s + priority: 100 - name: HAT-P-36 position: 12h33m03.909s +44d54m55.18s From fbb1977cdc34a84ac56e7ef447bef920a07e0e97 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:23:30 +1000 Subject: [PATCH 113/149] * Only do one iteration of the cam --- bin/pocs_shell | 77 +++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 8a9e3ecd9..762c83933 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -385,7 +385,7 @@ def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): return analyze_fn -def mount_rotation(pocs, base_dir=None, **kwargs): +def mount_rotation(pocs, base_dir=None, direction='east', **kwargs): mount = pocs.observatory.mount print_info("Doing rotation test") @@ -397,45 +397,44 @@ def mount_rotation(pocs, base_dir=None, **kwargs): rotate_fn = None # Start exposing on cameras - for direction in ['east', 'west']: - print_info("Rotating to {}".format(direction)) - pocs.say("Rotating to {}".format(direction)) - procs = dict() - for cam_name, cam in pocs.observatory.cameras.items(): - fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - if cam.is_primary: - rotate_fn = fn - - # Move mount - mount.move_direction(direction=direction, seconds=21) - - # Get exposures - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: - continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - pocs.say('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break + print_info("Rotating to {}".format(direction)) + pocs.say("Rotating to {}".format(direction)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + if cam.is_primary: + rotate_fn = fn - time.sleep(2) - try: - img_utils.make_pretty_image( - fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - pocs.say("Can't make image for {}".format(fn)) + # Move mount + mount.move_direction(direction=direction, seconds=21) + + # Get exposures + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + pocs.say('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image( + fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + pocs.say("Can't make image for {}".format(fn)) return rotate_fn From c36336a316f283fc0707aa8c8c6dfa5148c0a8c4 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:28:52 +1000 Subject: [PATCH 114/149] Show delta --- bin/pocs_shell | 85 ++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 762c83933..a7f6468ac 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -264,10 +264,17 @@ class PocsShell(Cmd): print_info("Rotate: {} {}".format(rotate_center, rotate_fn)) self.pocs.say("Rotate: {:0.2f} x {:0.2f}".format(rotate_center[0], rotate_center[1])) + d_x = pole_center[0] - rotate_center[0] + d_y = pole_center[1] - rotate_center[1] + + self.pocs.say("d_x: {}".format(d_x)) + self.pocs.say("d_y: {}".format(d_y)) + fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) print_info("Plot image: {}".format(plot_fn)) fig.tight_layout() + fig.title("dx: {} \t dy: {}".format(d_x, d_y)) fig.savefig(plot_fn) try: @@ -385,7 +392,7 @@ def polar_rotation(pocs, exp_time=30, base_dir=None, **kwargs): return analyze_fn -def mount_rotation(pocs, base_dir=None, direction='east', **kwargs): +def mount_rotation(pocs, base_dir=None, include_west=False, **kwargs): mount = pocs.observatory.mount print_info("Doing rotation test") @@ -397,44 +404,48 @@ def mount_rotation(pocs, base_dir=None, direction='east', **kwargs): rotate_fn = None # Start exposing on cameras - print_info("Rotating to {}".format(direction)) - pocs.say("Rotating to {}".format(direction)) - procs = dict() - for cam_name, cam in pocs.observatory.cameras.items(): - fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) - proc = cam.take_exposure(seconds=exp_time, filename=fn) - procs[fn] = proc - if cam.is_primary: - rotate_fn = fn - - # Move mount - mount.move_direction(direction=direction, seconds=21) - - # Get exposures - for fn, proc in procs.items(): - try: - outs, errs = proc.communicate(timeout=(exp_time + 15)) - except AttributeError: + for direction in ['east', 'west']: + if include_west is False and direction is 'west': continue - except KeyboardInterrupt: - print_warning('Pole test interrupted') - pocs.say('Pole test interrupted') - proc.kill() - outs, errs = proc.communicate() - break - except TimeoutExpired: - proc.kill() - outs, errs = proc.communicate() - break - time.sleep(2) - try: - img_utils.make_pretty_image( - fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) - img_utils.cr2_to_fits(fn, remove_cr2=True) - except AssertionError: - print_warning("Can't make image for {}".format(fn)) - pocs.say("Can't make image for {}".format(fn)) + print_info("Rotating to {}".format(direction)) + pocs.say("Rotating to {}".format(direction)) + procs = dict() + for cam_name, cam in pocs.observatory.cameras.items(): + fn = '{}/rotation_{}_{}.cr2'.format(base_dir, direction, cam_name.lower()) + proc = cam.take_exposure(seconds=exp_time, filename=fn) + procs[fn] = proc + if cam.is_primary: + rotate_fn = fn + + # Move mount + mount.move_direction(direction=direction, seconds=21) + + # Get exposures + for fn, proc in procs.items(): + try: + outs, errs = proc.communicate(timeout=(exp_time + 15)) + except AttributeError: + continue + except KeyboardInterrupt: + print_warning('Pole test interrupted') + pocs.say('Pole test interrupted') + proc.kill() + outs, errs = proc.communicate() + break + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + break + + time.sleep(2) + try: + img_utils.make_pretty_image( + fn, title='Alignment Test - Rotate {}'.format(direction), primary=True) + img_utils.cr2_to_fits(fn, remove_cr2=True) + except AssertionError: + print_warning("Can't make image for {}".format(fn)) + pocs.say("Can't make image for {}".format(fn)) return rotate_fn From e47e2e3b8f3989b2ba1c407abef0f024876d18f3 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:29:16 +1000 Subject: [PATCH 115/149] Check for west --- bin/pocs_shell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index a7f6468ac..0d2161220 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -405,7 +405,7 @@ def mount_rotation(pocs, base_dir=None, include_west=False, **kwargs): # Start exposing on cameras for direction in ['east', 'west']: - if include_west is False and direction is 'west': + if include_west is False and direction == 'west': continue print_info("Rotating to {}".format(direction)) From 9275772fcb2285a1a2a5e5562e7a3b9ae3b751a8 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:34:14 +1000 Subject: [PATCH 116/149] * Format delta --- bin/pocs_shell | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index 0d2161220..e81ba1be8 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -267,14 +267,14 @@ class PocsShell(Cmd): d_x = pole_center[0] - rotate_center[0] d_y = pole_center[1] - rotate_center[1] - self.pocs.say("d_x: {}".format(d_x)) - self.pocs.say("d_y: {}".format(d_y)) + self.pocs.say("d_x: {:0.2f}".format(d_x)) + self.pocs.say("d_y: {:0.2f}".format(d_y)) fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) - print_info("Plot image: {}".format(plot_fn)) + print_info("Plot image: {:0.2f}".format(plot_fn)) fig.tight_layout() - fig.title("dx: {} \t dy: {}".format(d_x, d_y)) + fig.title("dx: {} \t dy: {:0.2f}".format(d_x, d_y)) fig.savefig(plot_fn) try: From db6c44e4c8041d3305f6c6ef204aaae4464d423b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:35:40 +1000 Subject: [PATCH 117/149] Move title --- bin/pocs_shell | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index e81ba1be8..ded41cb52 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -274,7 +274,6 @@ class PocsShell(Cmd): print_info("Plot image: {:0.2f}".format(plot_fn)) fig.tight_layout() - fig.title("dx: {} \t dy: {:0.2f}".format(d_x, d_y)) fig.savefig(plot_fn) try: From 328210d3a91bfaadc455ef8d4c8d2a55833e0f6a Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:42:13 +1000 Subject: [PATCH 118/149] Write out hte stats --- bin/pocs_shell | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/pocs_shell b/bin/pocs_shell index ded41cb52..ff69e7be6 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -285,6 +285,9 @@ class PocsShell(Cmd): except Exception: print_warning("Can't link latest image") + with open('{}/center.txt'.format(base_dir), 'w') as f: + f.write('{},{},{},{},{},{}'.format(pole_center[0], pole_center[1], rotate_center[0], rotate_center[1], d_x, d_y)) + print_info("Done with polar alignment test") self.pocs.say("Done with polar alignment test") From e3254db3675788c3000eec1a106a9e74a24b2213 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 10 Apr 2017 16:44:01 +1000 Subject: [PATCH 119/149] * Fix small issues with plot --- bin/pocs_shell | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index ff69e7be6..d6c021d15 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -272,7 +272,7 @@ class PocsShell(Cmd): fig = polar_alignment.plot_center(pole_fn, rotate_fn, pole_center, rotate_center) - print_info("Plot image: {:0.2f}".format(plot_fn)) + print_info("Plot image: {}".format(plot_fn)) fig.tight_layout() fig.savefig(plot_fn) @@ -286,7 +286,8 @@ class PocsShell(Cmd): print_warning("Can't link latest image") with open('{}/center.txt'.format(base_dir), 'w') as f: - f.write('{},{},{},{},{},{}'.format(pole_center[0], pole_center[1], rotate_center[0], rotate_center[1], d_x, d_y)) + f.write('{},{},{},{},{},{}'.format(pole_center[0], pole_center[ + 1], rotate_center[0], rotate_center[1], d_x, d_y)) print_info("Done with polar alignment test") self.pocs.say("Done with polar alignment test") From 816c997de32cac0c675c05222c889b44ab50445b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 11 Apr 2017 15:10:40 +1000 Subject: [PATCH 120/149] Output some info about the drift --- pocs/observatory.py | 17 +++++++++++------ pocs/state/states/default/tracking.py | 4 +++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index d918d2e3d..ce4a18ef0 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -341,13 +341,18 @@ def update_tracking(self): else: ra_direction = 'east' - self.logger.info("Adjusting mount dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_ms * 1.5, dec_offset)) - if abs(dec_ms.value) >= 1. and abs(dec_ms.value) <= 10000: - self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(abs(dec_ms.value) * 1.5)) + dec_correction = abs(dec_ms.value) * 1.5 + ra_correction = abs(ra_ms.value) * 1.5 - self.logger.info("Adjusting mount ra: {} {:0.2f} {:0.2f}".format(ra_direction, ra_ms * 1.5, ra_offset)) - if abs(ra_ms.value) >= 1. and abs(ra_ms.value) <= 10000: - self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(abs(ra_ms.value) * 1.5)) + self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) + if dec_correction >= 1. and dec_correction <= 10000: + self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_correction)) + + self.logger.info("Adjusting RA: {} {:0.2f} {:0.2f}".format(ra_direction, ra_correction, ra_offset)) + if ra_correction >= 1. and ra_correction <= 10000: + self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_correction)) + + return ((ra_direction, ra_correction), (dec_direction, dec_correction)) def get_standard_headers(self, observation=None): """Get a set of standard headers diff --git a/pocs/state/states/default/tracking.py b/pocs/state/states/default/tracking.py index 601447041..d19515805 100644 --- a/pocs/state/states/default/tracking.py +++ b/pocs/state/states/default/tracking.py @@ -4,7 +4,9 @@ def on_enter(event_data): pocs.say("Checking our tracking") try: - pocs.observatory.update_tracking() + ra_info, dec_info = pocs.observatory.update_tracking() + pocs.say("Correcting drift: RA {} {}".format(ra_info[0], ra_info[1] * 1.5)) + pocs.say("Correcting drift: Dec {} {}".format(dec_info[0], dec_info[1] * 1.5)) except Exception as e: pocs.logger.warning("Problem adjusting tracking: {}".format(e)) From 480b0e440dbc095298834e792a5ab48e4231db15 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 11 Apr 2017 16:36:02 +1000 Subject: [PATCH 121/149] Show the arcsec delta, not the ms --- pocs/observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index ce4a18ef0..9e5895a90 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -352,7 +352,7 @@ def update_tracking(self): if ra_correction >= 1. and ra_correction <= 10000: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_correction)) - return ((ra_direction, ra_correction), (dec_direction, dec_correction)) + return ((ra_direction, ra_offset), (dec_direction, dec_offset)) def get_standard_headers(self, observation=None): """Get a set of standard headers From 1bf0eaf8288502e9af77ed46f7dc6069e3ac2d8d Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 11 Apr 2017 16:36:50 +1000 Subject: [PATCH 122/149] Show offsets --- pocs/state/states/default/tracking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/state/states/default/tracking.py b/pocs/state/states/default/tracking.py index d19515805..3504fa376 100644 --- a/pocs/state/states/default/tracking.py +++ b/pocs/state/states/default/tracking.py @@ -5,8 +5,8 @@ def on_enter(event_data): try: ra_info, dec_info = pocs.observatory.update_tracking() - pocs.say("Correcting drift: RA {} {}".format(ra_info[0], ra_info[1] * 1.5)) - pocs.say("Correcting drift: Dec {} {}".format(dec_info[0], dec_info[1] * 1.5)) + pocs.say("Correcting drift: RA {} {:.02f}".format(ra_info[0], ra_info[1])) + pocs.say("Correcting drift: Dec {} {:.02f}".format(dec_info[0], dec_info[1])) except Exception as e: pocs.logger.warning("Problem adjusting tracking: {}".format(e)) From 087c1405afe744dcb08d21988948ee6db58cf02f Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 11 Apr 2017 17:10:17 +1000 Subject: [PATCH 123/149] Increase range --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 9e5895a90..f75a0245f 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -345,11 +345,11 @@ def update_tracking(self): ra_correction = abs(ra_ms.value) * 1.5 self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) - if dec_correction >= 1. and dec_correction <= 10000: + if dec_correction >= 1. and dec_correction <= 50000: self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_correction)) self.logger.info("Adjusting RA: {} {:0.2f} {:0.2f}".format(ra_direction, ra_correction, ra_offset)) - if ra_correction >= 1. and ra_correction <= 10000: + if ra_correction >= 1. and ra_correction <= 50000: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_correction)) return ((ra_direction, ra_offset), (dec_direction, dec_offset)) From 9e4f3443eab1de697cdf224c24674acaf5d90282 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 11 Apr 2017 17:12:10 +1000 Subject: [PATCH 124/149] Correct --- pocs/observatory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index f75a0245f..d46bb22be 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -345,11 +345,11 @@ def update_tracking(self): ra_correction = abs(ra_ms.value) * 1.5 self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) - if dec_correction >= 1. and dec_correction <= 50000: + if dec_correction >= 1. and dec_correction <= 25000: self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_correction)) self.logger.info("Adjusting RA: {} {:0.2f} {:0.2f}".format(ra_direction, ra_correction, ra_offset)) - if ra_correction >= 1. and ra_correction <= 50000: + if ra_correction >= 1. and ra_correction <= 25000: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_correction)) return ((ra_direction, ra_offset), (dec_direction, dec_offset)) From 5d312bf5414150128c20f876a214717205d84091 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 12 Apr 2017 17:38:31 +1000 Subject: [PATCH 125/149] * Use a guide rate of 0.5 and set the max time to be the time length of an exposure (should probably be a little shorter actually) --- pocs/mount/mount.py | 4 ++-- pocs/observatory.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pocs/mount/mount.py b/pocs/mount/mount.py index 05724e047..f7441a5e3 100644 --- a/pocs/mount/mount.py +++ b/pocs/mount/mount.py @@ -472,7 +472,7 @@ def set_tracking_rate(self, direction='ra', delta=1.0): """Sets the tracking rate for the mount """ raise NotImplementedError - def get_ms_offset(self, offset): + def get_ms_offset(self, offset, guide_rate=0.5): """ Get offset in milliseconds at current speed Args: @@ -481,7 +481,7 @@ def get_ms_offset(self, offset): Returns: float: Offset in milliseconds at current speed """ - return (offset / (self.sidereal_rate * 0.9)).to(u.ms) + return (offset / (self.sidereal_rate * guide_rate)).to(u.ms) def query(self, cmd, params=None): """ Sends a query to TheSkyX and returns response. diff --git a/pocs/observatory.py b/pocs/observatory.py index d46bb22be..5527ad34f 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -344,12 +344,14 @@ def update_tracking(self): dec_correction = abs(dec_ms.value) * 1.5 ra_correction = abs(ra_ms.value) * 1.5 + max_time = 120 * 1000 # exp_time * ms + self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) - if dec_correction >= 1. and dec_correction <= 25000: + if dec_correction >= 1. and dec_correction <= max_time: self.mount.query('move_ms_{}'.format(dec_direction), '{:05.0f}'.format(dec_correction)) self.logger.info("Adjusting RA: {} {:0.2f} {:0.2f}".format(ra_direction, ra_correction, ra_offset)) - if ra_correction >= 1. and ra_correction <= 25000: + if ra_correction >= 1. and ra_correction <= max_time: self.mount.query('move_ms_{}'.format(ra_direction), '{:05.0f}'.format(ra_correction)) return ((ra_direction, ra_offset), (dec_direction, dec_offset)) From a7dc62c7b2f1bf5b70cf24cf7ba8820877c6d3ab Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 12 Apr 2017 18:46:34 +1000 Subject: [PATCH 126/149] * Update guide rate getting/setting * Use the actual guide rate for the ms offset, allowing for different rates for RA/Dec --- pocs/mount/ioptron.py | 8 +++++--- pocs/mount/mount.py | 16 +++++++++++++--- pocs/mount/serial.py | 4 +++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pocs/mount/ioptron.py b/pocs/mount/ioptron.py index 16a28aea8..6411ac3ce 100644 --- a/pocs/mount/ioptron.py +++ b/pocs/mount/ioptron.py @@ -211,9 +211,11 @@ def _set_initial_rates(self): self.logger.debug('Setting manual moving rate to max') self.query('set_button_moving_rate', 9) self.logger.debug("Mount guide rate: {}".format(self.query('get_guide_rate'))) - self.query('set_guide_rate', '9090') - self.guide_rate = self.query('get_guide_rate') - self.logger.debug("Mount guide rate: {}".format(self.guide_rate)) + self.query('set_guide_rate', '5050') + guide_rate = self.query('get_guide_rate') + self.ra_guide_rate = int(guide_rate[0:2]) / 100 + self.dec_guide_rate = int(guide_rate[2:]) / 100 + self.logger.debug("Mount guide rate: {} {}".format(self.ra_guide_rate, self.dec_guide_rate)) def _setup_location_for_mount(self): """ diff --git a/pocs/mount/mount.py b/pocs/mount/mount.py index f7441a5e3..4ec432ce6 100644 --- a/pocs/mount/mount.py +++ b/pocs/mount/mount.py @@ -71,7 +71,8 @@ def __init__(self, location, commands=None, *args, **kwargs self._state = 'Parked' self.sidereal_rate = ((360 * u.degree).to(u.arcsec) / (86164 * u.second)) - self.guide_rate = 0.9 # Sidereal + self.ra_guide_rate = 0.5 # Sidereal + self.dec_guide_rate = 0.5 # Sidereal self._tracking_rate = 1.0 # Sidereal self._tracking = 'Sidereal' self._movement_speed = '' @@ -97,7 +98,8 @@ def status(self): status = {} try: status['tracking_rate'] = '{:0.04f}'.format(self.tracking_rate) - status['guide_rate'] = self.guide_rate + status['ra_guide_rate'] = self.ra_guide_rate + status['dec_guide_rate'] = self.dec_guide_rate status['movement_speed'] = self.movement_speed current_coord = self.get_current_coordinates() @@ -472,7 +474,7 @@ def set_tracking_rate(self, direction='ra', delta=1.0): """Sets the tracking rate for the mount """ raise NotImplementedError - def get_ms_offset(self, offset, guide_rate=0.5): + def get_ms_offset(self, offset, axis='ra'): """ Get offset in milliseconds at current speed Args: @@ -481,6 +483,14 @@ def get_ms_offset(self, offset, guide_rate=0.5): Returns: float: Offset in milliseconds at current speed """ + + rates = { + 'ra': self.ra_guide_rate, + 'dec': self.dec_guide_rate, + } + + guide_rate = rates[axis] + return (offset / (self.sidereal_rate * guide_rate)).to(u.ms) def query(self, cmd, params=None): diff --git a/pocs/mount/serial.py b/pocs/mount/serial.py index 5de765796..d14385a11 100644 --- a/pocs/mount/serial.py +++ b/pocs/mount/serial.py @@ -246,7 +246,9 @@ def _update_status(self): self._is_tracking = 'Tracking' in self.state self._is_slewing = 'Slewing' in self.state - self.guide_rate = int(self.query('get_guide_rate')) + guide_rate = self.query('get_guide_rate') + self.ra_guide_rate = int(guide_rate[0:2]) / 100 + self.dec_guide_rate = int(guide_rate[2:]) / 100 status['timestamp'] = self.query('get_local_time') status['tracking_rate_ra'] = self.tracking_rate From b53db692c56471ce9c9d5b8a5db4e447bed2312f Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 12 Apr 2017 19:20:15 +1000 Subject: [PATCH 127/149] * Max time is set by serial command --- pocs/observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 5527ad34f..c6abe6850 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -344,7 +344,7 @@ def update_tracking(self): dec_correction = abs(dec_ms.value) * 1.5 ra_correction = abs(ra_ms.value) * 1.5 - max_time = 120 * 1000 # exp_time * ms + max_time = 99999 self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) if dec_correction >= 1. and dec_correction <= max_time: From 002bb870b139f6f40d19d0c8709ccf60ce568baf Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Wed, 12 Apr 2017 19:21:10 +1000 Subject: [PATCH 128/149] Max time still move --- pocs/observatory.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pocs/observatory.py b/pocs/observatory.py index c6abe6850..4a01762e8 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -345,6 +345,11 @@ def update_tracking(self): ra_correction = abs(ra_ms.value) * 1.5 max_time = 99999 + if dec_correction > max_time: + dec_correction = max_time + + if ra_correction > max_time: + ra_correction = max_time self.logger.info("Adjusting Dec: {} {:0.2f} {:0.2f}".format(dec_direction, dec_correction, dec_offset)) if dec_correction >= 1. and dec_correction <= max_time: From deb5f35497ca39f0c136cf46524d539c8331d185 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 13 Apr 2017 17:28:25 +1000 Subject: [PATCH 129/149] * Make sure button speed is always set when parking --- pocs/mount/ioptron.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pocs/mount/ioptron.py b/pocs/mount/ioptron.py index 6411ac3ce..377d3a7b2 100644 --- a/pocs/mount/ioptron.py +++ b/pocs/mount/ioptron.py @@ -194,6 +194,7 @@ def park(self): # The mount is currently not parking in correct position so we manually move it there. self.unpark() + self.query('set_button_moving_rate', 9) self.move_direction(direction='south', seconds=11.0) self._is_parked = True From 442cd6d83c0479d2c39d0ec01e9f21c30065248c Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 13 Apr 2017 17:35:08 +1000 Subject: [PATCH 130/149] * Let the `get_reading` method throw exception --- pocs/utils/rs232.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index c7952ea70..74a6bb9cc 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -37,7 +37,7 @@ def __init__(self, port=None, baudrate=115200, threaded=True, name="serial_data" self.ser.open() self.name = name - self.queue = deque([], 100) + self.queue = deque([], 10) self._is_listening = False self.loop_delay = 2. @@ -175,14 +175,7 @@ def get_reading(self): Returns: str: Item in queue """ - info = None - try: - ts, data = self.queue.popleft() - info = (ts, data) - except Exception: - pass - - return info + return self.queue.popleft() def clear_buffer(self): """ Clear Response Buffer """ From f471ce57e63d53262478a30ba61e5f54e231ae50 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 13 Apr 2017 17:39:42 +1000 Subject: [PATCH 131/149] * Better index check for deque --- pocs/utils/rs232.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 74a6bb9cc..01a1b63c6 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -175,7 +175,13 @@ def get_reading(self): Returns: str: Item in queue """ - return self.queue.popleft() + + try: + info = self.queue.popleft() + except IndexError: + raise IndexError + else: + return info def clear_buffer(self): """ Clear Response Buffer """ From 12fcd4ccf0c1d9cf45e51c96adc6bd393495843b Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 13 Apr 2017 17:57:54 +1000 Subject: [PATCH 132/149] Only keep one item in the deque --- pocs/utils/rs232.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/utils/rs232.py b/pocs/utils/rs232.py index 01a1b63c6..b6c47c6a7 100644 --- a/pocs/utils/rs232.py +++ b/pocs/utils/rs232.py @@ -37,7 +37,7 @@ def __init__(self, port=None, baudrate=115200, threaded=True, name="serial_data" self.ser.open() self.name = name - self.queue = deque([], 10) + self.queue = deque([], 1) self._is_listening = False self.loop_delay = 2. @@ -177,7 +177,7 @@ def get_reading(self): """ try: - info = self.queue.popleft() + info = self.queue.pop() except IndexError: raise IndexError else: From 9f17d0d9cb02c538cdb2085c9635bff8f3f1c971 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 13:13:46 +1000 Subject: [PATCH 133/149] * Use the pointing image as the reference image for tracking offsets * Store `pointing_image` inside the `current_observation` --- pocs/observatory.py | 57 ++++++++++++--------------- pocs/scheduler/observation.py | 2 + pocs/state/states/default/pointing.py | 6 ++- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 4a01762e8..9c107c14d 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -278,40 +278,33 @@ def analyze_recent(self): # Clear the offset info self.current_offset_info = None - ref_image_id, ref_image_path = self.current_observation.first_exposure + pointing_image = self.current_observation.pointing_image try: - # If we just finished the first exposure, solve the image so it can be reference - if self.current_observation.current_exp == 1: - ref_image = Image(ref_image_path, location=self.earth_location) - ref_solve_info = ref_image.solve_field() - - self.logger.debug("Reference Solve Info: {}".format(ref_solve_info)) - else: - # Get the image to compare - image_id, image_path = self.current_observation.last_exposure - - current_image = Image(image_path, location=self.earth_location) - ref_image = Image(ref_image_path, location=self.earth_location) - solve_info = current_image.solve_field() - - self.logger.debug("Solve Info: {}".format(solve_info)) - - # Get the offset between the two - self.current_offset_info = current_image.compute_offset(ref_image) - self.logger.debug('Offset Info: {}'.format(self.current_offset_info)) - - # Update the observation info with the offsets - self.db.observations.update({'image_id': image_id}, { - '$set': { - 'offset_info': { - 'd_ra': self.current_offset_info.delta_ra.value, - 'd_dec': self.current_offset_info.delta_dec.value, - 'magnitude': self.current_offset_info.magnitude.value, - 'unit': 'arcsec' - } - }, - }) + # Get the image to compare + image_id, image_path = self.current_observation.last_exposure + + current_image = Image(image_path, location=self.earth_location) + + solve_info = current_image.solve_field() + + self.logger.debug("Solve Info: {}".format(solve_info)) + + # Get the offset between the two + self.current_offset_info = current_image.compute_offset(pointing_image) + self.logger.debug('Offset Info: {}'.format(self.current_offset_info)) + + # Update the observation info with the offsets + self.db.observations.update({'image_id': image_id}, { + '$set': { + 'offset_info': { + 'd_ra': self.current_offset_info.delta_ra.value, + 'd_dec': self.current_offset_info.delta_dec.value, + 'magnitude': self.current_offset_info.magnitude.value, + 'unit': 'arcsec' + } + }, + }) except error.SolveError: self.logger.warning("Can't solve field, skipping") diff --git a/pocs/scheduler/observation.py b/pocs/scheduler/observation.py index 0413de21b..ccaecebcc 100644 --- a/pocs/scheduler/observation.py +++ b/pocs/scheduler/observation.py @@ -63,6 +63,8 @@ def __init__(self, field, exp_time=120 * u.second, min_nexp=60, self._min_duration = self.exp_time * self.min_nexp self._set_duration = self.exp_time * self.exp_set_size + self.pointing_image = None + self._seq_time = None self.current_exp = 0 diff --git a/pocs/state/states/default/pointing.py b/pocs/state/states/default/pointing.py index 020c6de5d..b40cfe60f 100644 --- a/pocs/state/states/default/pointing.py +++ b/pocs/state/states/default/pointing.py @@ -39,9 +39,13 @@ def on_enter(event_data): # WARNING!! Need to do better error checking here to make sure # the "current" observation is actually the current observation pointing_metadata = pocs.db.get_current('observations') - pointing_image = Image(pointing_metadata['data']['file_path']) + pointing_path = pointing_metadata['data']['file_path'] + + pointing_image = Image(pointing_path, location=pocs.observatory.earth_location) pointing_image.solve_field() + observation.pointing_image = pointing_image + pocs.logger.debug("Pointing file: {}".format(pointing_image)) pocs.say("Ok, I've got the pointing picture, let's see how close we are.") From 152e486b3f4dd0e8b76b9de15a4eee425e36af4f Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 13:23:13 +1000 Subject: [PATCH 134/149] * Adding header items for pointing image * Don't correct RA as much --- pocs/observatory.py | 2 +- pocs/state/states/default/pointing.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 9c107c14d..8fcc1c3b5 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -335,7 +335,7 @@ def update_tracking(self): ra_direction = 'east' dec_correction = abs(dec_ms.value) * 1.5 - ra_correction = abs(ra_ms.value) * 1.5 + ra_correction = abs(ra_ms.value) * 1.25 max_time = 99999 if dec_correction > max_time: diff --git a/pocs/state/states/default/pointing.py b/pocs/state/states/default/pointing.py index b40cfe60f..cd63b03cb 100644 --- a/pocs/state/states/default/pointing.py +++ b/pocs/state/states/default/pointing.py @@ -23,6 +23,7 @@ def on_enter(event_data): observation = pocs.observatory.current_observation fits_headers = pocs.observatory.get_standard_headers(observation=observation) + fits_headers['POINTING'] = 'True' pocs.logger.debug("Pointing headers: {}".format(fits_headers)) # Take pointing picture and wait for result From 1854deada5e5449547952f9f7b6f22df39ce3491 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 16:48:45 +1000 Subject: [PATCH 135/149] * Adding readout time to camera --- pocs/observatory.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 8fcc1c3b5..73d2b0129 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -614,6 +614,7 @@ def _create_cameras(self, **kwargs): raise error.CameraNotFound(msg="No port specified and auto_detect=False") camera_focuser = camera_config.get('focuser', None) + camera_readout = camera_config.get('readout_time', 6.0) else: # Set up a simulated camera with fully configured simulated focuser @@ -626,6 +627,7 @@ def _create_cameras(self, **kwargs): 'autofocus_step': (10, 20), 'autofocus_seconds': 0.1, 'autofocus_size': 500} + camera_readout = 0.5 camera_set_point = camera_config.get('set_point', None) camera_filter = camera_config.get('filter_type', None) @@ -644,7 +646,8 @@ def _create_cameras(self, **kwargs): port=camera_port, set_point=camera_set_point, filter_type=camera_filter, - focuser=camera_focuser) + focuser=camera_focuser, + readout_time=camera_readout) is_primary = '' if camera_info.get('primary', '') == cam.uid: From cb3b2e459b4ed47e92598f64bbeb6e5491b91809 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 17:43:10 +1000 Subject: [PATCH 136/149] Wait for the exposure process --- pocs/camera/canon_gphoto2.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pocs/camera/canon_gphoto2.py b/pocs/camera/canon_gphoto2.py index 0874336de..95c2d7982 100644 --- a/pocs/camera/canon_gphoto2.py +++ b/pocs/camera/canon_gphoto2.py @@ -132,11 +132,11 @@ def take_observation(self, observation, headers=None, filename=None, **kwargs): } metadata.update(headers) exp_time = kwargs.get('exp_time', observation.exp_time.value) - self.take_exposure(seconds=exp_time, filename=file_path) + proc = self.take_exposure(seconds=exp_time, filename=file_path) # Process the image after a set amount of time wait_time = exp_time + self.readout_time - t = Timer(wait_time, self.process_exposure, (metadata, camera_event,)) + t = Timer(wait_time, self.process_exposure, (metadata, camera_event, proc)) t.name = '{}Thread'.format(self.name) t.start() @@ -183,7 +183,7 @@ def take_exposure(self, seconds=1.0 * u.second, filename=None): else: return proc - def process_exposure(self, info, signal_event): + def process_exposure(self, info, signal_event, exposure_process=None): """Processes the exposure Converts the CR2 to a FITS file. If the camera is a primary camera, extract the @@ -195,6 +195,9 @@ def process_exposure(self, info, signal_event): signal_event (threading.Event): An event that is set signifying that the camera is done with this exposure """ + if exposure_process: + exposure_process.wait() + image_id = info['image_id'] file_path = info['file_path'] self.logger.debug("Processing {}".format(image_id)) From 46fedb9eceb21ebb16bc8f901495704201504fdd Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 17:45:19 +1000 Subject: [PATCH 137/149] * Adding timeout in `observing` state --- pocs/state/states/default/observing.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pocs/state/states/default/observing.py b/pocs/state/states/default/observing.py index ae406a837..520e1720c 100644 --- a/pocs/state/states/default/observing.py +++ b/pocs/state/states/default/observing.py @@ -2,6 +2,7 @@ from time import sleep wait_interval = 15. +timeout = 150. def on_enter(event_data): @@ -24,6 +25,9 @@ def on_enter(event_data): pocs.logger.debug('Waiting for images: {} seconds'.format(wait_time)) pocs.status() + if wait_interval > timeout: + raise error.Timeout + sleep(wait_interval) wait_time += wait_interval From eac63ab2b7cb9d54c6647069a6bac9ed5d489c17 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 19:38:46 +1000 Subject: [PATCH 138/149] * Increment minor version number to indicate we have tracking * Store images with `sequence_id` at top level --- pocs/camera/canon_gphoto2.py | 3 ++- pocs/version.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pocs/camera/canon_gphoto2.py b/pocs/camera/canon_gphoto2.py index 95c2d7982..bd8fff35d 100644 --- a/pocs/camera/canon_gphoto2.py +++ b/pocs/camera/canon_gphoto2.py @@ -199,6 +199,7 @@ def process_exposure(self, info, signal_event, exposure_process=None): exposure_process.wait() image_id = info['image_id'] + seq_id = info['sequence_id'] file_path = info['file_path'] self.logger.debug("Processing {}".format(image_id)) @@ -227,7 +228,7 @@ def process_exposure(self, info, signal_event, exposure_process=None): 'data': info, 'date': current_time(datetime=True), 'type': 'observations', - 'image_id': image_id, + 'sequence_id': seq_id, }) # Mark the event as done diff --git a/pocs/version.py b/pocs/version.py index e457f703c..e5831a262 100644 --- a/pocs/version.py +++ b/pocs/version.py @@ -1,6 +1,6 @@ # this file was automatically generated major = 0 minor = 1 -release = 1 +release = 2 version = '{}.{}.{}'.format(major, minor, release) From 6eec6f359b7a725a22dfbef9f6ee8181a529ae87 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 20:24:00 +1000 Subject: [PATCH 139/149] Fixing version test in dumb way for now --- pocs/tests/test_observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/tests/test_observatory.py b/pocs/tests/test_observatory.py index ef588719b..77b9440cb 100644 --- a/pocs/tests/test_observatory.py +++ b/pocs/tests/test_observatory.py @@ -167,7 +167,7 @@ def test_standard_headers(observatory): test_headers = { 'airmass': 1.091778, - 'creator': 'POCSv0.1.1', + 'creator': 'POCSv0.1.2', 'elevation': 3400.0, 'ha_mnt': 1.6844671878927793, 'latitude': 19.54, From d5c5454a018d349f0c83a7239cee6c5fdf615eed Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 21:10:38 +1000 Subject: [PATCH 140/149] * Since we store sequence_id at higher level we need to update appropriately --- pocs/observatory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 73d2b0129..ee195a188 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -295,7 +295,7 @@ def analyze_recent(self): self.logger.debug('Offset Info: {}'.format(self.current_offset_info)) # Update the observation info with the offsets - self.db.observations.update({'image_id': image_id}, { + self.db.observations.update({'data.image_id': image_id}, { '$set': { 'offset_info': { 'd_ra': self.current_offset_info.delta_ra.value, From 143c1d008ad618429fe724395efe7469124c8c89 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 22:28:07 +1000 Subject: [PATCH 141/149] * Take multiple 30 sec pointing images so we can also determine PE --- pocs/state/states/default/pointing.py | 66 ++++++++++++++++++--------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/pocs/state/states/default/pointing.py b/pocs/state/states/default/pointing.py index cd63b03cb..1bee2dc8d 100644 --- a/pocs/state/states/default/pointing.py +++ b/pocs/state/states/default/pointing.py @@ -1,8 +1,12 @@ from time import sleep -from pocs.images import Image +from ....images import Image +from ....utils import error wait_interval = 3. +timeout = 150. + +num_pointing_images = 8 def on_enter(event_data): @@ -19,40 +23,60 @@ def on_enter(event_data): try: pocs.say("Taking pointing picture.") - primary_camera = pocs.observatory.primary_camera observation = pocs.observatory.current_observation fits_headers = pocs.observatory.get_standard_headers(observation=observation) fits_headers['POINTING'] = 'True' pocs.logger.debug("Pointing headers: {}".format(fits_headers)) - # Take pointing picture and wait for result - camera_event = primary_camera.take_observation(observation, fits_headers, exp_time=30., filename='pointing') + for img_num in range(num_pointing_images): + camera_events = dict() + + for cam_name, camera in pocs.observatory.cameras.items(): + pocs.logger.debug("Exposing for camera: {}".format(cam_name)) + + try: + # Start the exposures + camera_event = camera.take_observation( + observation, fits_headers, exp_time=30., filename='pointing{}'.format(img_num)) + + camera_events[cam_name] = camera_event + + except Exception as e: + pocs.logger.error("Problem waiting for images: {}".format(e)) + + wait_time = 0. + while not all([event.is_set() for event in camera_events.values()]): + pocs.check_messages() + if pocs.interrupted: + pocs.say("Observation interrupted!") + break + + pocs.logger.debug('Waiting for images: {} seconds'.format(wait_time)) + pocs.status() - wait_time = 0. - while not camera_event.is_set(): - pocs.logger.debug('Waiting for pointing image: {} seconds'.format(wait_time)) - pocs.status() + if wait_interval > timeout: + raise error.Timeout - sleep(wait_interval) - wait_time += wait_interval + sleep(wait_interval) + wait_time += wait_interval - # WARNING!! Need to do better error checking here to make sure - # the "current" observation is actually the current observation - pointing_metadata = pocs.db.get_current('observations') - pointing_path = pointing_metadata['data']['file_path'] + # WARNING!! Need to do better error checking here to make sure + # the "current" observation is actually the current observation + pointing_metadata = pocs.db.get_current('observations') + pointing_path = pointing_metadata['data']['file_path'] - pointing_image = Image(pointing_path, location=pocs.observatory.earth_location) - pointing_image.solve_field() + pointing_image = Image(pointing_path, location=pocs.observatory.earth_location) + pointing_image.solve_field() - observation.pointing_image = pointing_image + observation.pointing_image = pointing_image - pocs.logger.debug("Pointing file: {}".format(pointing_image)) + pocs.logger.debug("Pointing file: {}".format(pointing_image)) - pocs.say("Ok, I've got the pointing picture, let's see how close we are.") + pocs.say("Ok, I've got the pointing picture, let's see how close we are.") - pocs.logger.debug("Pointing Coords: {}".format(pointing_image.pointing)) - pocs.logger.debug("Pointing Error: {}".format(pointing_image.pointing_error)) + pocs.logger.debug("Pointing Coords: {}".format(pointing_image.pointing)) + pocs.logger.debug("Pointing Error: {}".format(pointing_image.pointing_error)) # separation = pointing_image.pointing_error.magnitude.value From 8c7db3c0134fde44ac5ab1e43a017bf4d8d2b610 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sun, 16 Apr 2017 22:31:00 +1000 Subject: [PATCH 142/149] * Pointing image with zero padded name --- pocs/state/states/default/pointing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pocs/state/states/default/pointing.py b/pocs/state/states/default/pointing.py index 1bee2dc8d..7a7ef004a 100644 --- a/pocs/state/states/default/pointing.py +++ b/pocs/state/states/default/pointing.py @@ -38,7 +38,7 @@ def on_enter(event_data): try: # Start the exposures camera_event = camera.take_observation( - observation, fits_headers, exp_time=30., filename='pointing{}'.format(img_num)) + observation, fits_headers, exp_time=30., filename='pointing{:02d}'.format(img_num)) camera_events[cam_name] = camera_event From 78affd3b124a17eca4158e9361a3b42c8117e928 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 17 Apr 2017 15:16:59 +1000 Subject: [PATCH 143/149] * Better cleanup --- pocs/observatory.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pocs/observatory.py b/pocs/observatory.py index ee195a188..9cbfe4b70 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -179,11 +179,19 @@ def cleanup_observations(self): try: dir_name = os.path.join( self.config['directories']['images'], + 'fields', observation.field.field_name, self.primary_camera.uid, observation.seq_time ) + # Pack the fits filts + for f in glob('{}/*.fits'.format(dir_name)): + try: + img_utils.fpack(f) + except Exception as e: + self.logger.warning('Could not compress fits file: {}'.format(e)) + # Remove .solved files self.logger.debug('Removing .solved files') for f in glob('{}/*.solved'.format(dir_name)): From dcd7854c43302c26dce7e8c1ab37f5313688c758 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Mon, 17 Apr 2017 21:29:26 +1000 Subject: [PATCH 144/149] * RA at 1x sidereal * Back to just one pointing image --- pocs/observatory.py | 2 +- pocs/state/states/default/pointing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 9cbfe4b70..431cb4e57 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -343,7 +343,7 @@ def update_tracking(self): ra_direction = 'east' dec_correction = abs(dec_ms.value) * 1.5 - ra_correction = abs(ra_ms.value) * 1.25 + ra_correction = abs(ra_ms.value) * 1. max_time = 99999 if dec_correction > max_time: diff --git a/pocs/state/states/default/pointing.py b/pocs/state/states/default/pointing.py index 7a7ef004a..94f150e54 100644 --- a/pocs/state/states/default/pointing.py +++ b/pocs/state/states/default/pointing.py @@ -6,7 +6,7 @@ wait_interval = 3. timeout = 150. -num_pointing_images = 8 +num_pointing_images = 1 def on_enter(event_data): From 173056d6d23be3ad51ab2c8b53ea52fc804e481f Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Tue, 18 Apr 2017 06:27:31 +1000 Subject: [PATCH 145/149] * More explicit cleanup procedure --- pocs/observatory.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pocs/observatory.py b/pocs/observatory.py index 431cb4e57..abfa52eb2 100644 --- a/pocs/observatory.py +++ b/pocs/observatory.py @@ -1,5 +1,4 @@ import os -import time from collections import OrderedDict from datetime import datetime @@ -176,22 +175,27 @@ def cleanup_observations(self): for seq_time, observation in self.scheduler.observed_list.items(): self.logger.debug("Housekeeping for {}".format(observation)) + dir_name = "{}/fields/{}/{}/{}/".format( + self.config['directories']['images'], + observation.field.field_name, + self.primary_camera.uid, + observation.seq_time, + ) + + self.logger.debug("Cleaning dir: {}".format(dir_name)) + + # Pack the fits filts try: - dir_name = os.path.join( - self.config['directories']['images'], - 'fields', - observation.field.field_name, - self.primary_camera.uid, - observation.seq_time - ) - - # Pack the fits filts + self.logger.debug("Packing FITS files") for f in glob('{}/*.fits'.format(dir_name)): try: img_utils.fpack(f) except Exception as e: self.logger.warning('Could not compress fits file: {}'.format(e)) + except Exception as e: + self.logger.warning('Problem with cleanup cleaning FITS:'.format(e)) + try: # Remove .solved files self.logger.debug('Removing .solved files') for f in glob('{}/*.solved'.format(dir_name)): @@ -199,7 +203,10 @@ def cleanup_observations(self): os.remove(f) except OSError as e: self.logger.warning('Could not delete file: {}'.format(e)) + except Exception as e: + self.logger.warning('Problem with cleanup removing solved:'.format(e)) + try: jpg_list = glob('{}/*.jpg'.format(dir_name)) if len(jpg_list) == 0: @@ -219,7 +226,7 @@ def cleanup_observations(self): self.logger.warning('Could not delete file: {}'.format(e)) except Exception as e: - self.logger.warning('Problem with cleanup:'.format(e)) + self.logger.warning('Problem with cleanup creating timelapse:'.format(e)) self.logger.debug('Cleanup for {} finished'.format(observation)) From 28bbde5dc69f4e77c4b1449a1008ba8c354dc94e Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Thu, 20 Apr 2017 16:38:09 +1000 Subject: [PATCH 146/149] * Write all drift alignment results to the same file (TODO: Add headers ) --- bin/pocs_shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index d6c021d15..a5edf0fe9 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -285,8 +285,8 @@ class PocsShell(Cmd): except Exception: print_warning("Can't link latest image") - with open('{}/center.txt'.format(base_dir), 'w') as f: - f.write('{},{},{},{},{},{}'.format(pole_center[0], pole_center[ + with open('/var/panoptes/images/drift_align/center.txt'.format(base_dir), 'a') as f: + f.write('{}.{},{},{},{},{},{}'.format(start_time, pole_center[0], pole_center[ 1], rotate_center[0], rotate_center[1], d_x, d_y)) print_info("Done with polar alignment test") From b7d3d06221fd6adc76962751873a1cb27f148c63 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 22 Apr 2017 19:38:18 +1000 Subject: [PATCH 147/149] * Add newline to file --- bin/pocs_shell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pocs_shell b/bin/pocs_shell index a5edf0fe9..20f8aff73 100755 --- a/bin/pocs_shell +++ b/bin/pocs_shell @@ -286,7 +286,7 @@ class PocsShell(Cmd): print_warning("Can't link latest image") with open('/var/panoptes/images/drift_align/center.txt'.format(base_dir), 'a') as f: - f.write('{}.{},{},{},{},{},{}'.format(start_time, pole_center[0], pole_center[ + f.write('{}.{},{},{},{},{},{}\n'.format(start_time, pole_center[0], pole_center[ 1], rotate_center[0], rotate_center[1], d_x, d_y)) print_info("Done with polar alignment test") From 5586ae7fabfeebbc4a40522c9ac4a2cf5e586abf Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 22 Apr 2017 21:35:47 +1000 Subject: [PATCH 148/149] * Adding an `improve_wcs` that will run through WCS option again and try to refine --- pocs/utils/images.py | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index 423508a37..2bc25cffd 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -182,6 +182,77 @@ def get_solve_field(fname, replace=True, remove_extras=True, **kwargs): return out_dict +def improve_wcs(fname, remove_extras=True, replace=True, **kwargs): + verbose = kwargs.get('verbose', False) + out_dict = {} + output = None + errs = None + + if verbose: + print("Entering improve_wcs: {}".format(fname)) + + options = [ + '--continue', + '--t', '3', + '--q', '0.01', + '--V', fname, + ] + + proc = solve_field(fname, solve_opts=options, **kwargs) + try: + output, errs = proc.communicate(timeout=kwargs.get('timeout', 30)) + except subprocess.TimeoutExpired: + proc.kill() + raise error.Timeout("Timeout while solving") + else: + if verbose: + print("Output: {}", output) + print("Errors: {}", errs) + + if not os.path.exists(fname.replace('.fits', '.solved')): + raise error.SolveError('File not solved') + + try: + # Handle extra files created by astrometry.net + new = fname.replace('.fits', '.new') + rdls = fname.replace('.fits', '.rdls') + axy = fname.replace('.fits', '.axy') + xyls = fname.replace('.fits', '-indx.xyls') + + if replace and os.path.exists(new): + # Remove converted fits + os.remove(fname) + # Rename solved fits to proper extension + os.rename(new, fname) + + out_dict['solved_fits_file'] = fname + else: + out_dict['solved_fits_file'] = new + + if remove_extras: + for f in [rdls, xyls, axy]: + if os.path.exists(f): + os.remove(f) + + except Exception as e: + warn('Cannot remove extra files: {}'.format(e)) + + if errs is not None: + warn("Error in solving: {}".format(errs)) + else: + # Read the EXIF information from the CR2 + if fname.endswith('cr2'): + out_dict.update(read_exif(fname)) + + try: + out_dict.update(fits.getheader(fname)) + except OSError: + if verbose: + print("Can't read fits header for {}".format(fname)) + + return out_dict + + def crop_data(data, box_width=200, center=None, verbose=False): """ Return a cropped portion of the image From a4935ff2c570d2454bdfa599e843d7e67ee2e670 Mon Sep 17 00:00:00 2001 From: Wilfred Tyler Gee Date: Sat, 22 Apr 2017 21:48:36 +1000 Subject: [PATCH 149/149] * Silly singly letter options --- pocs/utils/images.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pocs/utils/images.py b/pocs/utils/images.py index 2bc25cffd..71d03334a 100644 --- a/pocs/utils/images.py +++ b/pocs/utils/images.py @@ -193,9 +193,9 @@ def improve_wcs(fname, remove_extras=True, replace=True, **kwargs): options = [ '--continue', - '--t', '3', - '--q', '0.01', - '--V', fname, + '-t', '3', + '-q', '0.01', + '-V', fname, ] proc = solve_field(fname, solve_opts=options, **kwargs)