Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
146 changes: 15 additions & 131 deletions socs/agents/starcam_lat/agent.py
Original file line number Diff line number Diff line change
@@ -1,134 +1,12 @@
import argparse
import socket
import struct
import time
from os import environ

import txaio
from ocs import ocs_agent, site_config
from ocs.ocs_twisted import TimeoutLock


class StarcamHelper:
"""Functions to control and retrieve data from the starcam.

Parameters
----------
ip_addres: str
IP address of the starcam computer.
port: int
Port of the starcam computer.
timeout: float
Socket connection timeout in seconds. Defaults to 10 seconds.

"""

def __init__(self, ip_address, port, timeout=10):
self.ip = ip_address
self.port = port
self.server_addr = (self.ip, self.port)
self.comm = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.comm.connect(self.server_addr)
self.comm.settimeout(timeout)

def pack_and_send_cmds(self):
"""Packs commands and parameters to be sent to the starcam and sends.

Returns:
list: Values sent to the starcam.

"""
logodds = 1e8
latitude = -22.9586
longitude = -67.7875
height = 5200.0
exposure = 700
timelimit = 1
set_focus_to_amount = 0
auto_focus_bool = 1
start_focus = 0
end_focus = 0
step_size = 5
photos_per_focus = 3
infinity_focus_bool = 0
set_aperture_steps = 0
max_aperture_bool = 0
make_HP_bool = 0
use_HP_bool = 0
spike_limit_value = 3
dynamic_hot_pixels_bool = 1
r_smooth_value = 2
high_pass_filter_bool = 0
r_high_pass_filter_value = 10
centroid_search_border_value = 1
filter_return_image_bool = 0
n_sigma_value = 2
star_spacing_value = 15
values = [logodds,
latitude,
longitude,
height,
exposure,
timelimit,
set_focus_to_amount,
auto_focus_bool,
start_focus,
end_focus,
step_size,
photos_per_focus,
infinity_focus_bool,
set_aperture_steps,
max_aperture_bool,
make_HP_bool,
use_HP_bool,
spike_limit_value,
dynamic_hot_pixels_bool,
r_smooth_value,
high_pass_filter_bool,
r_high_pass_filter_value,
centroid_search_border_value,
filter_return_image_bool,
n_sigma_value,
star_spacing_value]
# Pack values into the command for the camera
self.cmds_for_camera = struct.pack('ddddddfiiiiiiiiiifffffffff',
*values)
# send commands to the camera
self.comm.sendto(self.cmds_for_camera, (self.ip, self.port))
print("Commands sent to camera.")
# Return the list of values
return values

def get_astrom_data(self):
"""Receives and unpacks data from the starcam.

Returns:
dict: Dictionary of unpacked data.
"""
(scdata_raw, _) = self.comm.recvfrom(256)
data = struct.unpack_from("dddddddddddddiiiiiiiiddiiiiiiiiiiiiiifiii",
scdata_raw)
keys = ['c_time',
'gmt',
'blob_num',
'obs_ra',
'astrom_ra',
'obs_dec',
'fr',
'ps',
'alt',
'az',
'ir',
'astrom_solve_time',
'camera_time']
# Create a dictionary of the unpacked data
astrom_data = [data[i] for i in range(len(keys))]
astrom_data_dict = {keys[i]: astrom_data[i] for i in range(len(keys))}
return astrom_data_dict

def close(self):
"""Closes the socket connection."""
self.comm.close()
from socs.agents.starcam_lat.drivers import StarcamHelper


class StarcamAgent:
Expand Down Expand Up @@ -159,14 +37,11 @@ def __init__(self, agent, ip_address, port):
self.log = agent.log
self.take_data = False
self.lock = TimeoutLock()
self.starcam = StarcamHelper(ip_address, port)

agg_params = {'frame_length': 60}
self.agent.register_feed("starcamera", record=True,
agg_params=agg_params, buffer_time=1)
try:
self.starcam = StarcamHelper(ip_address, port)
except socket.timeout:
self.log.error("Starcam connection has timed out.")
return False, "Timeout"

@ocs_agent.param('_')
def send_commands(self, session, params=None):
Expand All @@ -182,7 +57,8 @@ def send_commands(self, session, params=None):
f"{self.lock.job} is already running.")
return False, "Could not acquire lock."
self.log.info("Sending commands.")
self.starcam.pack_and_send_cmds()
self.starcam.send_cmds()
self.log.info("Commands sent to camera.")
return True, "Sent commands to the starcam."

@ocs_agent.param('_')
Expand Down Expand Up @@ -231,8 +107,16 @@ def acq(self, session, params=None):
'block_name': 'astrometry',
'data': {}
}
# get astrometry data
astrom_data_dict = self.starcam.get_astrom_data()
try:
astrom_data_dict = self.starcam.get_astrom_data()
if session.degraded:
self.log.info("Connection re-established.")
session.degraded = False
except ConnectionError:
self.log.error("Failed to get data from star camera. Check network connection.")
session.degraded = True
time.sleep(1)
continue
# update the data dictionary+session and publish
data['data'].update(astrom_data_dict)
session.data.update(data['data'])
Expand Down
123 changes: 123 additions & 0 deletions socs/agents/starcam_lat/drivers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import struct

from socs.tcp import TCPInterface


class StarcamHelper(TCPInterface):
"""Functions to control and retrieve data from the starcam.

Parameters
----------
ip_addres: str
IP address of the starcam computer.
port: int
Port of the starcam computer.
timeout: float
Socket connection timeout in seconds. Defaults to 10 seconds.

"""

def __init__(self, ip_address, port, timeout=10):
# Set up the TCP Interface
super().__init__(ip_address, port, timeout)

def send_cmds(self):
"""Send commands and parameters to the starcam."""
cmds = self._pack_cmds()
self.comm.send(cmds)

@staticmethod
def _pack_cmds():
"""Packs commands and parameters to be sent to the starcam.

Returns:
bytes: Packed bytes object to send to the starcam.

"""
logodds = 1e8
latitude = -22.9586
longitude = -67.7875
height = 5200.0
exposure = 700
timelimit = 1
set_focus_to_amount = 0
auto_focus_bool = 1
start_focus = 0
end_focus = 0
step_size = 5
photos_per_focus = 3
infinity_focus_bool = 0
set_aperture_steps = 0
max_aperture_bool = 0
make_HP_bool = 0
use_HP_bool = 0
spike_limit_value = 3
dynamic_hot_pixels_bool = 1
r_smooth_value = 2
high_pass_filter_bool = 0
r_high_pass_filter_value = 10
centroid_search_border_value = 1
filter_return_image_bool = 0
n_sigma_value = 2
star_spacing_value = 15
values = [logodds,
latitude,
longitude,
height,
exposure,
timelimit,
set_focus_to_amount,
auto_focus_bool,
start_focus,
end_focus,
step_size,
photos_per_focus,
infinity_focus_bool,
set_aperture_steps,
max_aperture_bool,
make_HP_bool,
use_HP_bool,
spike_limit_value,
dynamic_hot_pixels_bool,
r_smooth_value,
high_pass_filter_bool,
r_high_pass_filter_value,
centroid_search_border_value,
filter_return_image_bool,
n_sigma_value,
star_spacing_value]

# Pack values into the command for the camera
return struct.pack('ddddddfiiiiiiiiiifffffffff', *values)

def get_astrom_data(self):
"""Receives and unpacks data from the starcam.

Returns:
dict: Dictionary of unpacked data.
"""
scdata_raw = self.comm.recv(256)
return self._unpack_response(scdata_raw)

@staticmethod
def _unpack_response(response):
data = struct.unpack_from("dddddddddddddiiiiiiiiddiiiiiiiiiiiiiifiii",
response)
keys = ['c_time',
'gmt',
'blob_num',
'obs_ra',
'astrom_ra',
'obs_dec',
'fr',
'ps',
'alt',
'az',
'ir',
'astrom_solve_time',
'camera_time']

# Create a dictionary of the unpacked data
astrom_data = [data[i] for i in range(len(keys))]
astrom_data_dict = {keys[i]: astrom_data[i] for i in range(len(keys))}
return astrom_data_dict
6 changes: 6 additions & 0 deletions tests/agents/test_starcam_lat_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from socs.agents.starcam_lat.drivers import StarcamHelper # noqa: F401


def test__pack_cmds():
cmds = StarcamHelper._pack_cmds()
assert cmds == b'\x00\x00\x00\x00\x84\xd7\x97A\x13\xf2A\xcff\xf56\xc0fffff\xf2P\xc0\x00\x00\x00\x00\x00P\xb4@\x00\x00\x00\x00\x00\xe0\x85@\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@@\x00\x00\x80?\x00\x00\x00@\x00\x00\x00\x00\x00\x00 A\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00@\x00\x00pA'