Skip to content

Commit

Permalink
Hotfix commits (wwg)
Browse files Browse the repository at this point in the history
  • Loading branch information
WWGolay committed Dec 20, 2024
1 parent acdc882 commit 026a9e1
Show file tree
Hide file tree
Showing 7 changed files with 389 additions and 87 deletions.
244 changes: 244 additions & 0 deletions asidemo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
import ctypes
import pathlib
from ctypes import *
from enum import Enum

import cv2
import numpy as np

lib_path = pathlib.Path(
r"C:\Users\MACRO\Downloads\ASI_Camera_SDK\ASI_Camera_SDK\ASI_Windows_SDK_V1.37\ASI SDK\lib\x64\ASICamera2.dll"
)
print(lib_path)
asi = CDLL(lib_path) # 调用SDK lib
cameraID = 0 # 初始化相关全局变量
width = 0
height = 0
bufferSize = 0


class ASI_IMG_TYPE(Enum): # 定义相关枚举量
ASI_IMG_RAW8 = 0
ASI_IMG_RGB24 = 1
ASI_IMG_RAW16 = 2
ASI_IMG_Y8 = 3
ASI_IMG_END = -1


class ASI_BOOL(Enum):
ASI_FALSE = 0
ASI_TRUE = 1


class ASI_BAYER_PATTERN(Enum):
ASI_BAYER_RG = 0
ASI_BAYER_BG = 1
ASI_BAYER_GR = 2
ASI_BAYER_GB = 3


class ASI_EXPOSURE_STATUS(Enum):
ASI_EXP_IDLE = 0 # idle states, you can start exposure now
ASI_EXP_WORKING = 1 # exposing
ASI_EXP_SUCCESS = 2 # exposure finished and waiting for download
ASI_EXP_FAILED = 3 # exposure failed, you need to start exposure again


class ASI_ERROR_CODE(Enum):
ASI_SUCCESS = 0
ASI_ERROR_INVALID_INDEX = 1 # no camera connected or index value out of boundary
ASI_ERROR_INVALID_ID = 2 # invalid ID
ASI_ERROR_INVALID_CONTROL_TYPE = 3 # invalid control type
ASI_ERROR_CAMERA_CLOSED = 4 # camera didn't open
ASI_ERROR_CAMERA_REMOVED = (
5 # failed to find the camera, maybe the camera has been removed
)
ASI_ERROR_INVALID_PATH = 6 # cannot find the path of the file
ASI_ERROR_INVALID_FILEFORMAT = 7
ASI_ERROR_INVALID_SIZE = 8 # wrong video format size
ASI_ERROR_INVALID_IMGTYPE = 9 # unsupported image formate
ASI_ERROR_OUTOF_BOUNDARY = 10 # the startpos is out of boundary
ASI_ERROR_TIMEOUT = 11 # timeout
ASI_ERROR_INVALID_SEQUENCE = 12 # stop capture first
ASI_ERROR_BUFFER_TOO_SMALL = 13 # buffer size is not big enough
ASI_ERROR_VIDEO_MODE_ACTIVE = 14
ASI_ERROR_EXPOSURE_IN_PROGRESS = 15
ASI_ERROR_GENERAL_ERROR = 16 # general error, eg: value is out of valid range
ASI_ERROR_INVALID_MODE = 17 # the current mode is wrong
ASI_ERROR_END = 18


class ASI_CAMERA_INFO(Structure): # 定义ASI_CAMERA_INFO 结构体
_fields_ = [
("Name", c_char * 64),
("CameraID", c_int),
("MaxHeight", c_long),
("MaxWidth", c_long),
("IsColorCam", c_int),
("BayerPattern", c_int),
("SupportedBins", c_int * 16),
("SupportedVideoFormat", c_int * 8),
("PixelSize", c_double),
("MechanicalShutter", c_int),
("ST4Port", c_int),
("IsCoolerCam", c_int),
("IsUSB3Host", c_int),
("IsUSB3Camera", c_int),
("ElecPerADU", c_float),
("BitDepth", c_int),
("IsTriggerCam", c_int),
("Unused", c_char * 16),
]


class ASI_CONTROL_TYPE(Enum): # Control type 定义 ASI_CONTROL_TYPE 结构体
ASI_GAIN = 0
ASI_EXPOSURE = 1
ASI_GAMMA = 2
ASI_WB_R = 3
ASI_WB_B = 4
ASI_OFFSET = 5
ASI_BANDWIDTHOVERLOAD = 6
ASI_OVERCLOCK = 7
ASI_TEMPERATURE = 8 # return 10*temperature
ASI_FLIP = 9
ASI_AUTO_MAX_GAIN = 10
ASI_AUTO_MAX_EXP = 11 # micro second
ASI_AUTO_TARGET_BRIGHTNESS = 12 # target brightness
ASI_HARDWARE_BIN = 13
ASI_HIGH_SPEED_MODE = 14
ASI_COOLER_POWER_PERC = 15
ASI_TARGET_TEMP = 16 # not need *10
ASI_COOLER_ON = 17
ASI_MONO_BIN = 18 # lead to less grid at software bin mode for color camera
ASI_FAN_ON = 19
ASI_PATTERN_ADJUST = 20
ASI_ANTI_DEW_HEATER = 21


def init(): # 相机初始化
global width
global height
global cameraID

num = asi.ASIGetNumOfConnectedCameras() # 获取连接相机数
if num == 0:
print("No camera connection!")
return
print("Number of connected cameras: ", num)

camInfo = ASI_CAMERA_INFO()
getCameraProperty = asi.ASIGetCameraProperty
getCameraProperty.argtypes = [POINTER(ASI_CAMERA_INFO), c_int]
getCameraProperty.restype = c_int

for i in range(0, num):
asi.ASIGetCameraProperty(camInfo, i) # 以index获取相机属性

cameraID = camInfo.CameraID

err = asi.ASIOpenCamera(cameraID) # 打开相机
if err != 0:
return
print("Open Camera Success")

err = asi.ASIInitCamera(cameraID) # 初始化相机
if err != 0:
return
print("Init Camera Success")

width = camInfo.MaxWidth
height = camInfo.MaxHeight
_bin = 1
startx = 0
starty = 0
imageType = ASI_IMG_TYPE.ASI_IMG_RAW16

err = asi.ASISetROIFormat(
cameraID, width, height, _bin, imageType.value
) # SetROIFormat
if err != 0:
print("Set ROI Format Fail")
return
print("Set ROI Format Success")

asi.ASISetStartPos(cameraID, startx, starty) # SetStartPos


def getFrame(): # 获取图像帧
global bufferSize
buffersize = width * height

buffer = (c_ubyte * 2 * buffersize)()

err = asi.ASIStartExposure(cameraID, 0) # 开始曝光
if err != 0:
print("Start Exposure Fail")
return
print("Start Exposure Success")

getExpStatus = asi.ASIGetExpStatus
getExpStatus.argtypes = [c_int, POINTER(c_int)]
getExpStatus.restype = c_int
expStatus = c_int()

getDataAfterExp = asi.ASIGetDataAfterExp
getDataAfterExp.argtypes = [c_int, POINTER(c_ubyte) * 2, c_int]
getDataAfterExp.restype = c_int
buffer = (c_ubyte * 2 * buffersize)()

getExpStatus(cameraID, expStatus)
print("status: ", expStatus)

# c_int转int
sts = expStatus.value
while sts == ASI_EXPOSURE_STATUS.ASI_EXP_WORKING.value: # 获取曝光状态
getExpStatus(cameraID, expStatus)
sts = expStatus.value

if sts != ASI_EXPOSURE_STATUS.ASI_EXP_SUCCESS.value:
print("Exposure Fail")
return

err = getDataAfterExp(cameraID, buffer, buffersize) # 曝光成功,获取buffer
if err != 0:
print("GetDataAfterExp Fail")
return
print("getDataAfterExp Success")

return buffer


def closeCamera(): # 关闭相机
err = asi.ASIStopVideoCapture(cameraID)
if err != 0:
print("Stop Capture Fail")
return
print("Stop Capture Success")

err = asi.ASICloseCamera(cameraID)
if err != 0:
print("Close Camera Fail")
return
print("Close Camera Success")


def setExpValue(val): # 设置曝光时间
# setControlValue = asi.ASISetControlValue
# setControlValue.argtypes = [c_int, ASI_CONTROL_TYPE, c_long, ASI_BOOL]
# setControlValue.restype = c_int
err = asi.ASISetControlValue(
cameraID, ASI_CONTROL_TYPE.ASI_EXPOSURE.value, val, ASI_BOOL.ASI_FALSE.value
)


def setGainValue(val): # 设置增益
err = asi.ASISetControlValue(
cameraID, ASI_CONTROL_TYPE.ASI_GAIN.value, val, ASI_BOOL.ASI_FALSE.value
)


def setBiasValue(val):
err = asi.ASISetControlValue(
cameraID, ASI_CONTROL_TYPE.ASI_OFFSET.value, val, ASI_BOOL.ASI_FALSE.value
)
64 changes: 40 additions & 24 deletions pyscope/observatory/observatory.py
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ def save_last_image(
hdr = self.generate_header_info(
filename, frametyp, custom_header, history, maxim, allowed_overwrite
)
# update RADECSYS key to RADECSYSa
# update RADECSYS key to RADECSYSa
if "RADECSYS" in hdr:
hdr["RADECSYSa"] = hdr["RADECSYS"]
hdr.pop("RADECSYS", None)
Expand All @@ -1321,7 +1321,6 @@ def save_last_image(
logger.exception(f"Error generating header information: {e}")
hdu = fits.PrimaryHDU(img_array)


hdu.writeto(filename, overwrite=overwrite)

return True
Expand Down Expand Up @@ -1760,6 +1759,7 @@ def run_autofocus(
use_current_pointing=False,
save_images=False,
save_path=None,
binning=2, # HOTFIX for 6200
):
"""Runs the autofocus routine"""

Expand Down Expand Up @@ -1800,7 +1800,9 @@ def run_autofocus(
autofocus_time = self.observatory_time.isot.replace(":", "-")

if save_path is None:
save_path = Path(os.getcwd(),"images","autofocus",f"{autofocus_time}").resolve()
save_path = Path(
os.getcwd(), "images", "autofocus", f"{autofocus_time}"
).resolve()

focus_values = []
for i, position in enumerate(test_positions):
Expand All @@ -1819,6 +1821,9 @@ def run_autofocus(
time.sleep(0.1)
logger.info("Focuser moved.")

# Set binning
self.camera.BinX = binning

logger.info("Taking %s second exposure..." % exposure)
self.camera.StartExposure(exposure, True)
while not self.camera.ImageReady:
Expand All @@ -1827,15 +1832,14 @@ def run_autofocus(

logger.info("Calculating mean star fwhm...")
if not save_images:
save_path = Path(tempfile.gettempdir(),f"{autofocus_time}").resolve()
save_path = Path(
tempfile.gettempdir(), f"{autofocus_time}"
).resolve()
if not save_path.exists():
save_path.mkdir(parents=True)
fname = (
save_path
/ f"FOCUS{int(position)}.fit"
)
fname = save_path / f"FOCUS{int(position)}.fit"

self.save_last_image(fname, frametyp="Focus")
self.save_last_image(fname, frametyp="Focus", overwrite=True)

# Removed for hotfix for PlateSolve2
# cat = detect_sources_photutils(
Expand Down Expand Up @@ -1865,32 +1869,42 @@ def run_autofocus(
# result_err = np.sqrt(np.diag(pcov))[0]

# Run platesolve 2 from cmd line
platesolve2_path = Path(r'C:\Program Files (x86)\PlaneWave Instruments\PlaneWave Interface 4\PlateSolve2\PlateSolve2.exe').resolve()
#print(platesolve2_path)
results_path = Path(save_path / 'results.txt').resolve()
#print(f"Results path: {results_path}")
image_path = glob.glob(str(save_path / '*.fit'))[0]
#print(f"Image path: {image_path}")
platesolve2_path = Path(
r"C:\Program Files (x86)\PlaneWave Instruments\PlaneWave Interface 4\PlateSolve2\PlateSolve2.exe"
).resolve()
# print(platesolve2_path)
results_path = Path(save_path / "results.txt").resolve()
# print(f"Results path: {results_path}")
image_path = glob.glob(str(save_path / "*.fit"))[0]
# print(f"Image path: {image_path}")
logger.info("Running PlateSolve2...")
procid = os.spawnv(os.P_NOWAIT, platesolve2_path, [f'"{platesolve2_path}" {image_path},{results_path},180'])

procid = os.spawnv(
os.P_NOWAIT,
platesolve2_path,
[f'"{platesolve2_path}" {image_path},{results_path},180'],
)

while results_path.exists() == False:
time.sleep(0.1)
# Read results
with open(results_path, 'r') as f:
with open(results_path, "r") as f:
results = f.read()
while results == '':
while results == "":
time.sleep(0.1)
with open(results_path, 'r') as f:
with open(results_path, "r") as f:
results = f.read()

print(f"Results path: {results_path}")
print(results)
results = results.split(',')
results = results.split(",")
# Remove whitespace
results = [x.strip() for x in results]
print(results)
result, fwhm, result_err = float(results[0]), float(results[1]), float(results[2])
result, fwhm, result_err = (
float(results[0]),
float(results[1]),
float(results[2]),
)
print(f"Best focus: {result}")
print(f"FWHM: {fwhm}")
print(f"Focus error: {result_err}")
Expand Down Expand Up @@ -1973,6 +1987,7 @@ def repositioning(
tolerance=3,
exposure=10,
readout=0,
binning=2, # HOTFIX: HARDCODED FOR ASI6200
save_images=False,
save_path="./",
settle_time=5,
Expand Down Expand Up @@ -2096,6 +2111,7 @@ def repositioning(

logger.info("Taking %.2f second exposure" % exposure)
self.camera.ReadoutMode = readout
self.camera.BinX = binning
self.camera.StartExposure(exposure, True)
while not self.camera.ImageReady:
time.sleep(0.1)
Expand Down Expand Up @@ -2303,11 +2319,11 @@ def take_flats(
self.telescope.Tracking = False
logger.info("Tracking off")

'''if self.cover_calibrator is not None:
"""if self.cover_calibrator is not None:
if self.cover_calibrator.CoverState != "NotPresent":
logger.info("Opening the cover calibrator")
self.cover_calibrator.OpenCover()
logger.info("Cover open")'''
logger.info("Cover open")"""

if gain is not None:
logger.info("Setting the camera gain to %i" % gain)
Expand Down
Loading

0 comments on commit 026a9e1

Please sign in to comment.