mirror of
https://github.com/eddyem/CCD_Capture.git
synced 2025-12-06 10:45:13 +03:00
Added Apogee support
This commit is contained in:
parent
644de638ca
commit
64a2ec11a0
14
APOGEE_cameras/CMakeLists.txt
Normal file
14
APOGEE_cameras/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
set(CCDLIB devapogee)
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(${CCDLIB} REQUIRED usefull_macros apogeec>=1.71 libusb)
|
||||
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
|
||||
include_directories(${${CCDLIB}_INCLUDE_DIRS} ..)
|
||||
link_directories(${${CCDLIB}_LIBRARY_DIRS})
|
||||
|
||||
add_library(${CCDLIB} SHARED ${SRC})
|
||||
target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -fPIC)
|
||||
install(TARGETS ${CCDLIB} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
338
APOGEE_cameras/apogee.c
Normal file
338
APOGEE_cameras/apogee.c
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* This file is part of the CCD_Capture project.
|
||||
* Copyright 2023 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <libapogee.h>
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <usb.h>
|
||||
#include <usefull_macros.h>
|
||||
|
||||
|
||||
#include "basestructs.h"
|
||||
//#include "omp.h"
|
||||
|
||||
|
||||
extern Camera camera;
|
||||
static int ncameras = 0;
|
||||
static int isopened = FALSE;
|
||||
static int osw = 0; // overscan width
|
||||
static int hbin = 1, vbin = 1;
|
||||
static int is16bit = 1;
|
||||
static int isobject = 0;
|
||||
static int maxbinv = 0, maxbinh = 0; // max binning
|
||||
static char camname[BUFSIZ] = {0};
|
||||
static double expt[2] = {0.}; // min/max exposition time
|
||||
static double exptime = 0.; // actual exposition time
|
||||
static double tstart = 0.; // exposure start time
|
||||
static char whynot[BUFSIZ]; // temporary buffer for error messages
|
||||
static int imW = 0, imH = 0; // size of output image
|
||||
static int pid = -1, vid = -1;
|
||||
static int isexposuring = 0;
|
||||
|
||||
static void disconnect(){
|
||||
FNAME();
|
||||
if(!isopened) return;
|
||||
ApnGlueExpAbort();
|
||||
ApnGlueClose();
|
||||
isopened = FALSE;
|
||||
}
|
||||
|
||||
static void cancel(){
|
||||
//if(!isexposuring) return;
|
||||
FNAME();
|
||||
ApnGlueReset();
|
||||
//ApnGlueExpAbort();
|
||||
//ApnGlueStopExposure();
|
||||
DBG("OK");
|
||||
}
|
||||
|
||||
static int ndev(){
|
||||
ncameras = 1;
|
||||
if(ApnGlueOpen(ncameras)) ncameras = 0;
|
||||
else ApnGlueClose();
|
||||
DBG("Found %d cameras", ncameras);
|
||||
camera.Ndevices = ncameras;
|
||||
return ncameras;
|
||||
}
|
||||
/*
|
||||
static void reset_usb_port(){
|
||||
if(vid < 0 || pid < 0) return;
|
||||
int fd, rc;
|
||||
char buf[FILENAME_MAX*3], *d = NULL, *f = NULL;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
int found = 0;
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
for(bus = usb_busses; bus && !found; bus = bus->next) {
|
||||
for(dev = bus->devices; dev && !found; dev = dev->next) {
|
||||
if (dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid){
|
||||
found = 1;
|
||||
d = bus->dirname;
|
||||
f = dev->filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found){
|
||||
ERR(_("Device not found"));
|
||||
return;
|
||||
}
|
||||
DBG("found camera device, reseting");
|
||||
snprintf(buf, sizeof(buf), "/dev/bus/usb/%s/%s", d,f);
|
||||
fd = open(buf, O_WRONLY);
|
||||
if(fd < 0){
|
||||
ERR("Can't open device file %s: %s", buf, strerror(errno));
|
||||
return;
|
||||
}
|
||||
WARNX("Resetting USB device %s", buf);
|
||||
rc = ioctl(fd, USBDEVFS_RESET, 0);
|
||||
if(rc < 0){
|
||||
perror("Error in ioctl");
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
}*/
|
||||
|
||||
static int setdevno(int n){
|
||||
FNAME();
|
||||
if(n > ncameras - 1) return FALSE;
|
||||
if(ApnGlueOpen(n)) return FALSE;
|
||||
ApnGlueExpAbort();
|
||||
ApnGluePowerResume();
|
||||
ApnGlueReset();
|
||||
char *msg = ApnGlueGetInfo(&pid, &vid);
|
||||
DBG("CAMERA msg:\n%s\n", msg);
|
||||
char *f = strstr(msg, "Model: ");
|
||||
if(f){
|
||||
f += strlen("Model: ");
|
||||
char *e = strchr(f, '\n');
|
||||
size_t l = (e) ? (size_t)(e-f) : strlen(f);
|
||||
if(l >= BUFSIZ) l = BUFSIZ - 1;
|
||||
snprintf(camname, l, "%s", f);
|
||||
}
|
||||
ApnGlueGetMaxValues(expt, &camera.array.w, &camera.array.h, &osw, NULL, &maxbinh, &maxbinv, NULL, NULL);
|
||||
DBG("MAX format: W/H: %d/%d; osw=%d, binh/v=%d/%d", camera.array.w, camera.array.h, osw, maxbinh, maxbinv);
|
||||
double x, y;
|
||||
ApnGlueGetGeom(&x, &y);
|
||||
camera.pixX = x, camera.pixY = y;
|
||||
camera.field.w = camera.array.w - osw;
|
||||
camera.field.h = camera.array.h;
|
||||
DBG("Pixel size W/H: %g/%g; field w/h: %d/%d", x, y, camera.field.w, camera.field.h);
|
||||
;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int modelname(char *buf, int bufsz){
|
||||
strncpy(buf, camname, bufsz);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int shutter(shutter_op cmd){
|
||||
int op = (cmd == SHUTTER_OPEN) ? 1 : 0;
|
||||
ApnGlueOpenShutter(op);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int geometrylimits(frameformat *l, frameformat *s){
|
||||
if(l) *l = camera.array;
|
||||
if(s) *s = (frameformat){.w = 1, .h = 1, .xoff = 1, .yoff = 1};
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int sett(float t){
|
||||
ApnGlueSetTemp(t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int setfanspd(fan_speed s){
|
||||
ApnGlueSetFan((int) s);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int preflash(int n){
|
||||
if(n > 0) n = 1; else n = 0;
|
||||
ApnGluePreFlash(n);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// 0 - 12 bit, 1 - 16bit
|
||||
static int setbitdepth(int i){
|
||||
DBG("set bit depth %d", i);
|
||||
Apn_Resolution res = (i) ? Apn_Resolution_SixteenBit : Apn_Resolution_TwelveBit;
|
||||
ApnGlueSetDatabits(res);
|
||||
is16bit = i;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int setfastspeed(int fast){
|
||||
DBG("set fast speed %d", fast);
|
||||
unsigned short spd = (fast) ? AdcSpeed_Fast : AdcSpeed_Normal;
|
||||
ApnGlueSetSpeed(spd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int setgeometry(frameformat *f){
|
||||
if(!f) return FALSE;
|
||||
int ow = (f->w > camera.field.w) ? camera.array.w - f->w : f->w;
|
||||
if(ow < 0) ow = 0;
|
||||
if(ApnGlueSetExpGeom(f->w * hbin, f->h * vbin, ow, 0, hbin, vbin,
|
||||
f->xoff, f->yoff, &imW, &imH, whynot)){
|
||||
WARNX("Can't set geometry: %s", whynot);
|
||||
}else{
|
||||
camera.geometry = *f;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int setbin(int binh, int binv){
|
||||
DBG("set bin v/h: %d/%d", binv, binh);
|
||||
if(binh > maxbinh || binv > maxbinv) return FALSE;
|
||||
hbin = binh; vbin = binv;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int tcold(float *t){
|
||||
if(!t) return FALSE;
|
||||
double dt;
|
||||
ApnGlueGetTemp(&dt);
|
||||
*t = dt;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int thot(float *t){
|
||||
if(t) *t = ApnGlueGetHotTemp();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int startexp(){
|
||||
tstart = dtime();
|
||||
DBG("Start exposition");
|
||||
CCDerr r = ApnGlueStartExp(&exptime, isobject);
|
||||
if(ALTA_OK != r){
|
||||
/*reset_usb_port();
|
||||
r = ApnGlueStartExp(&exptime, isobject);
|
||||
if(ALTA_OK != r){*/
|
||||
ApnGlueReset();
|
||||
DBG("Error starting exp: %d", (int)r);
|
||||
return FALSE;
|
||||
//}
|
||||
}
|
||||
isexposuring = 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int frametype(int islight){
|
||||
DBG("set frame type %d", islight);
|
||||
isobject = islight;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int setexp(float t){
|
||||
DBG("start exp %g, min: %g, max: %g", t, expt[0], expt[1]);
|
||||
if(t < expt[0] || t > expt[1]) return FALSE; // too big or too small exptime
|
||||
exptime = t;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int getbin(int *h, int *v){
|
||||
DBG("get bin v/h: %d/%d", vbin, hbin);
|
||||
if(h) *h = hbin;
|
||||
if(v) *v = vbin;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int pollcapt(capture_status *st, float *remain){
|
||||
DBG("Poll capture, tremain=%g", dtime() - tstart);
|
||||
if(dtime() - tstart > 5.){ // capture error?
|
||||
ApnGlueExpAbort();
|
||||
if(*st) *st = CAPTURE_ABORTED;
|
||||
return FALSE;
|
||||
}
|
||||
if(remain) *remain = dtime() - tstart;
|
||||
if(st) *st = CAPTURE_PROCESS;
|
||||
if(ApnGlueExpDone()){
|
||||
if(st) *st = CAPTURE_READY;
|
||||
isexposuring = 0;
|
||||
DBG("Capture ready");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int capture(IMG *ima){
|
||||
FNAME();
|
||||
if(!ima || !ima->data) return FALSE;
|
||||
if(ApnGlueReadPixels((uint16_t*)ima->data, imW * imH, whynot)){
|
||||
WARNX("Can't read image: %s", whynot);
|
||||
return FALSE;
|
||||
}
|
||||
ima->bitpix = is16bit ? 16 : 12;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int ffalse(_U_ float f){ return FALSE; }
|
||||
static int fpfalse(_U_ float *f){ return FALSE; }
|
||||
static int ifalse(_U_ int i){ return FALSE; }
|
||||
//static int vtrue(){ return TRUE; }
|
||||
static int ipfalse(_U_ int *i){ return FALSE; }
|
||||
|
||||
/*
|
||||
* Global objects: camera, focuser and wheel
|
||||
*/
|
||||
Camera camera = {
|
||||
.check = ndev,
|
||||
.close = disconnect,
|
||||
.pollcapture = pollcapt,
|
||||
.capture = capture,
|
||||
.cancel = cancel,
|
||||
.startexposition = startexp,
|
||||
// setters:
|
||||
.setDevNo = setdevno,
|
||||
.setbrightness = ffalse,
|
||||
.setexp = setexp,
|
||||
.setgain = ffalse,
|
||||
.setT = sett,
|
||||
.setbin = setbin,
|
||||
.setnflushes = preflash,
|
||||
.shuttercmd = shutter,
|
||||
.confio = ifalse,
|
||||
.setio = ifalse,
|
||||
.setframetype = frametype, // set DARK or NORMAL: no shutter -> no darks
|
||||
.setbitdepth = setbitdepth,
|
||||
.setfastspeed = setfastspeed,
|
||||
.setgeometry = setgeometry,
|
||||
.setfanspeed = setfanspd,
|
||||
// getters:
|
||||
.getbrightness = fpfalse,
|
||||
.getModelName = modelname,
|
||||
.getgain = fpfalse,
|
||||
.getmaxgain = fpfalse,
|
||||
.getgeomlimits = geometrylimits,
|
||||
.getTcold = tcold,
|
||||
.getThot = thot,
|
||||
.getTbody = fpfalse,
|
||||
.getbin = getbin,
|
||||
.getio = ipfalse,
|
||||
};
|
||||
@ -17,6 +17,7 @@ option(FLI "Add support of FLI cameras" OFF)
|
||||
option(BASLER "Add support of BASLER cameras" OFF)
|
||||
option(HIKROBOT "Add support of HIKROBOT cameras" OFF)
|
||||
option(FLYCAP "Add support of Grasshopper FlyCap cameras" OFF)
|
||||
option(APOGEE "Add support of Apogee cameras" OFF)
|
||||
|
||||
# default flags
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra -std=gnu99")
|
||||
@ -96,7 +97,9 @@ endif()
|
||||
if(FLYCAP)
|
||||
add_subdirectory(GRH_cameras)
|
||||
endif()
|
||||
|
||||
if(APOGEE)
|
||||
add_subdirectory(APOGEE_cameras)
|
||||
endif()
|
||||
|
||||
# directory should contain dir locale/ru for gettext translations
|
||||
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CCD/CMOS imaging server
|
||||
=======================
|
||||
|
||||
Supports FLI cameras/focusers/wheels and cameras: ZWO, Basler, HikRobot.
|
||||
Supports FLI cameras/focusers/wheels and cameras: ZWO, Basler, HikRobot, PointGrey, Apogee.
|
||||
Allows to run as standalone application or imaging server/client.
|
||||
|
||||
To restart server (e.g. if hardware was off) kill it with SIGUSR1
|
||||
@ -10,10 +10,12 @@ To restart server (e.g. if hardware was off) kill it with SIGUSR1
|
||||
|
||||
cmake options:
|
||||
|
||||
- `-DAPOGEE=ON` - compile Apogee plugin
|
||||
- `-DDEBUG=ON` - make with a lot debugging info
|
||||
- `-DIMAGEVIEW=ON` - compile with image viewer support (only for standalone) (OpenGL!!!)
|
||||
- `-DBASLER=ON` - compile Basler support plugin
|
||||
- `-DFLI=ON` - compile FLI support plugin
|
||||
- `-DFLYCAPT=ON` - compile GrassHopper PointGrey plugin
|
||||
- `-DHIKROBOT=ON` - compile HikRobot support plugin
|
||||
- `-DZWO=ON` - compile ZWO support plugin
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-02-28 17:05+0300\n"
|
||||
"POT-Creation-Date: 2023-03-06 17:25+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -474,12 +474,12 @@ msgstr ""
|
||||
msgid "Can't set brightness to %g"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:725 server.c:230
|
||||
#: ccdfunc.c:725 server.c:229
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:737 server.c:231
|
||||
#: ccdfunc.c:737 server.c:230
|
||||
msgid "Can't set given geometry"
|
||||
msgstr ""
|
||||
|
||||
@ -525,7 +525,7 @@ msgstr ""
|
||||
msgid "Capture frame %d"
|
||||
msgstr ""
|
||||
|
||||
#: ccdfunc.c:781 ccdfunc.c:831 server.c:125
|
||||
#: ccdfunc.c:781 ccdfunc.c:831 server.c:124
|
||||
msgid "Can't start exposition"
|
||||
msgstr ""
|
||||
|
||||
@ -547,7 +547,7 @@ msgstr ""
|
||||
msgid "%d seconds till pause ends\n"
|
||||
msgstr ""
|
||||
|
||||
#: server.c:168
|
||||
#: server.c:167
|
||||
msgid "No camera device"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-02-28 17:05+0300\n"
|
||||
"POT-Creation-Date: 2023-03-01 08:54+0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -162,7 +162,7 @@ msgstr "
|
||||
msgid "Can't set active wheel number"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
|
||||
|
||||
#: ccdfunc.c:725 server.c:230
|
||||
#: ccdfunc.c:725 server.c:229
|
||||
#, c-format
|
||||
msgid "Can't set binning %dx%d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
|
||||
@ -190,7 +190,7 @@ msgstr "
|
||||
msgid "Can't set gain to %g"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
|
||||
|
||||
#: ccdfunc.c:737 server.c:231
|
||||
#: ccdfunc.c:737 server.c:230
|
||||
msgid "Can't set given geometry"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
|
||||
|
||||
@ -213,7 +213,7 @@ msgstr "
|
||||
msgid "Can't set wheel position %d"
|
||||
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
|
||||
|
||||
#: ccdfunc.c:781 ccdfunc.c:831 server.c:125
|
||||
#: ccdfunc.c:781 ccdfunc.c:831 server.c:124
|
||||
msgid "Can't start exposition"
|
||||
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
|
||||
|
||||
@ -289,7 +289,7 @@ msgstr "
|
||||
msgid "N flushes before exposing (default: 1)"
|
||||
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
|
||||
|
||||
#: server.c:168
|
||||
#: server.c:167
|
||||
msgid "No camera device"
|
||||
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
|
||||
|
||||
|
||||
2
server.c
2
server.c
@ -885,7 +885,7 @@ static hresult imsendhandler(int fd, _U_ const char *key, _U_ const char *val){
|
||||
if(!ima.data || !ima.h || !ima.w) return RESULT_FAIL;
|
||||
// send image as raw data w*h*2
|
||||
if(!sendimage(fd, ima.data, 2*ima.h*ima.w)) return RESULT_DISCONNECTED;
|
||||
return RESULT_OK;
|
||||
return RESULT_SILENCE;
|
||||
}
|
||||
|
||||
static hresult imsizehandler(int fd, const char *key, _U_ const char *val){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user