这份文档是关于整套PXSDK(Software Development Kit),PXSDKCLR(CLR运行时),PxViewer(基于WPF的windows界面),areadetector(基于EPICS的类UNIX平台上的实时分布式控制系统)的面向用户和二次开发人员的文档。
# 一. PXSDK 高性能的相机控制接口
# Quick Start 快速上手
# 介绍
PXSDK是用于控制PixelX相机产品的最底层软件开发库。对于比较新的相机产品以及同一相机的新功能,将首先在这套软件开发库中体现出来并给予支持。PXSDK提供了一系列的C风格的接口,并提供了一套非常有用的宏定义,对于上层软件的开发有很大帮助。简言之,使用PXSDK进行二次开发需要用户有相关的知识背景,但是允许用户进行最全面、最底层的操作。
# 安装
首先,请安装libusb,并确保设备已被正确驱动。在所有依赖都已经满足的情况下,为了正常使用PXSDK,用户需要两个关键的文件:PXSDK.h
和PXSDK的动态链接库
,用户可以通过手工编译PXSDK来获得这两个文件。
对于windows用户: 如果使用的是
Visual Studio
,请将PXSDK.h
加入到项目的header file
中,并将适应于目标平台的PXSDK.dll
加入到项目的外部依赖项里。我们推荐的环境是Windows 10 + Visual Studio professional 2019
。对于Linux 用户: 如果使用的是
gcc/clang
,请将PXSDK.h
放入项目文件夹内,或者在编译时加入-I
参数加入PXSDK.h
所在的目录,或者修改项目Makefile/CMakeList
。同时,将适合目标平台的libPXSDK.so
放入/usr/local/lib
中,并在编译时加入-lPXSDK
选项。为了正确的运行编译生成的可执行文件,可能需要修改LD_LIBRARY_PATH
。我们建议使用的平台是Linux4.14+gcc8
(Jun 2019)对于BSD/MacOS用户: 参见Linux章节。由于缺乏完善的测试,我们不建议在这些平台上部署PXSDK。
# Hello world
在正确安装了PXSDK的情况下,我们很快就可以实现对相机的控制。接下来我们将实现一个可以对相机进行初始化、设置一次强制对齐,并进行一次拍照,清理资源并推出的小程序。
在程序的开头,请include PXSDK的头文件,我们的demo程序使用的是C++风格的接口,因此我们需要写这样的include语句:
##include "LibusbCamera.h"
##include "PixelxCamera.h"
##include "private.h"
##include "libusbUtils.h"
##include "PXSDK.h"
##include "cmos4040.h"
在主函数里,首先,我们利用list_devices()
函数列出目前插在电脑上的所有USB设备的PID
和VID
,然后让使用者选择要使用哪一个设备。
list_devices();
cout << "Select a device whose index is: ";
cin >> device_index;
然后我们将初始化一个libusb_device
,这是libusb(也即帮助我们实现对usb驱动的封装的库)提供的设备抽象指针,通过find_device
函数来实现这一功能:
libusb_device *device = find_device(device_index);
if (device == NULL) {
printf("index out of range! exit...\n");
return -1;
}
对返回值进行判断是一种良好的编码习惯。如果前面这些操作都没有发生错误,则意味着相机已经连接在设备上、上电正常并且被系统识别到了。此时我们可以初始化相机设备了。初始化行为由Initialize
函数完成。
CMOS4040Camera *camera = new CMOS4040Camera();
camera->Initialize(device);
这里需要说明一下,PXSDK的接口函数的返回值都是无符号整数,并且我们约定了一套标准的返回值:如果返回PIXELX_SUCCESS
(这个宏对应的无符号整数是20007
), 说明操作成功。如果不是PIXELX_SUCCESS
那么可能要根据故障码做出一定的诊断,或者是对程序做一些修改,这种情况下程序应该退出,而不是继续对相机执行操作。
另外值得说明的一点是,这里使用了C++风格的接口:初始化一个CMOS4040
相机对象的实例,并执行这个实例的Initialize
方法。实际上也可以直接调用C风格的接口,但是这两种接口不能混用。
接下来我们需要打开相机的散热风扇、开始制冷,这两步操作可以用如下的语句实现:
camera->SetCoolerTemp(targettemp);
camera->CoolerOn();
camera->FanStatusSet(1);
这里targettemp是一个表示制冷目标温度的浮点数。PXSDK对于很多具有“开关”意义的功能都提供了两种风格的接口:一种是直接调用一个名字里包含Set/Unset
或是On/off
的、不带参数的函数,一种是利用参数的值来表达开关的意思,名字以Set
结尾的函数。这主要是为了不同的编程习惯而做的考虑,实际的实现是一样的。
接下来我们将要设置获取图像的模式,当然也可以保持默认。PICMode
函数可以设置图像的模式:
camera->PICMode(pic_mode);
这里忽略了返回值的检查,实际上我们总是应该检查一下返回值。如果所有这几步设置都正确的完成了(也就是说返回了PIXELX_SUCCESS
),我们可以开始曝光了:
camera->StartExposure();
从设计的角度来说,PXSDK的函数接口都是阻塞式的,简而言之,就是“我们一定会完成操作并返回操作成功,或者是操作失败并返回对应的错误码”,而不是做了操作而不管操作的结果。但是曝光函数并不是这样的:对于天文观测来说,曝光时间很长,让整个程序阻塞在曝光函数上并不是一个明智之举。因此StartExposure
函数只是下发曝光命令并返回,随后PXSDK将会完成实际上的支持曝光的工作。用户可以在等待的时候做些别的事情,然后通过GetAcquisitionStatus
函数来了解曝光线程的工作状态:
while (camera->GetAcquisitionStatus() == PIXELX_ACQUIRING) {
cout << "acquiring..." << endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
loop_count++;
if (loop_count == 50000) {
cerr << "max loop count, sth error in readout..." << endl;
break;
}
}
如果曝光依然在进行,那么GetAcquisitionStatus
将会返回PIXELX_ACQUIRING
,这里我们每隔10毫秒检查一下曝光状态。在循环中,我们还会累加一个计数器来确定曝光总共持续了多久,并且当计数器超过了50000(也就是50万毫秒)的时候跳出循环,这是我们认为超时了,可以怀疑设备是否有问题,或者是有一些配置项没有被正确配置。
另一个有相似作用的函数叫WaitForAcquisition
,这个函数是阻塞的,他会保持阻塞直到图片数据已经放入缓冲区(也就是一段内存中)。
camera->WaitForAcquisition()
如果这个函数返回了PIXELX_SUCCESS
,那就说明整个曝光、读图流程都已经完成了,接下来我们可以读取图片并把他保存成一个fits图了。PXSDK的SaveAsFITS
接口将这些功能打包了起来
camera->SaveAsFITS(“MyFirstFits.fits”);
最后,别忘了清理一下:
camera->ShutDown();
# 编译运行
我们把这个demo程序保存为HelloWorld.cpp
。对于windows VisualStudio用户,把HelloWorld.cpp
加入你的项目并点击“生成“,就可以运行了。对于Linux用户,请输入:
g++ HelloWorld.cpp –o a.out –lPXSDK
接下来执行:
./a.out
就可以运行这个程序了。
# Documentation 接口文档
PXSDK的接口文档由Doxygen生成,请转至: pxsdk api online doxygen
# 二. PxViewer
基于WPF的CCD控制GUI
# Quick Start 快速上手
# Introduction 介绍
PxViewer是一套基于WPF开发的适用于Windows的GUI程序。PxViewer通过CLR
运行时调用PXSDK从而完成对相机控制。PxViewer集成了对相机进行初始化、配置曝光参数、读取和显示图片已经对图像进行一定程度的处理的功能。
# Installation 安装
对于非开发性质的用户,可以通过下载我们提供的的msi
文件安装。
对于开发者,首先请安装PxViewer的各个依赖项:libusb,usb驱动。
######## 使用 Visual Studio 2019 编译安装
- 使用
Git Bash
检查更新并构建项目,依次执行以下命令
$ cd PxViewer
$ git submodule init
$ git submodule update
$ cd PXSDK2
$ git checkout master
$ mkdir build
$ cd build
$ cmake ..
- 使用 Visual Studio 2019 打开
PxViewer\PxViewer.sln
文件,打开后的界面如下图
在右侧(红框中)的解决方案资源管理器中生成 PXSDK ,如下图所示
再以同样的方式依次生成 PXSDKCLR 和 PxViewer 。 全部生成成功后,点击软件编辑栏的启动按钮,如下图所示
- 启动后出现如下图界面
6.生成的相机控制界面如下图(未连接相机时操作按钮显示为灰色)
# First Snapshot 开始拍照
在拍照之前,请确保:相机已经连接电源,usb驱动和libusb套件已经正确安装,打开设备管理器时可以看到一台libusbk
设备,并且其pid
和vid
和预期一致。
如果这一步完成了,那么接下里可以点击PxViewer图标打开PxViewer的主界面。现在我们可以点击菜单栏的Camera
标签,再点击菜单栏下方的Acquisition Set
按钮:
图1 点击Camera标签下的Acquisition Set按钮
在弹出的对话框里,我们可以详细的配置相机的各个配置项。此时此刻我们只需要保持默认配置不变,就可以得到一张不错的照片了。
图2 点击Acquisition Set 按钮
关闭对话框,点击Start Expose
按钮:
图3 Start Expose对话框
稍候片刻,我们将看到界面中弹出了一张新的照片:
图4 获得照片
至此,一套完整的从打开程序到获得照片的流程就已经结束了。
# GUI Docmentation 图形界面文档
# 总览 Introduction
如下图所示:
图1 PxViewer主界面
在标签栏我们可以看到三个不同选项,分别对应PxViewer的三大基本功能: Image Tab主要包含和图片处理相关的功能,包括 Image Subtraction,Region,Pixel Map, Luminous Statistics,Left Hand Rotation, Right Hand Rotation,Y Axis Invert, X Axis Invert, ROI Frame 这几个子功能。
图2 Image Tab
Camera Tab主要包含与相机配置、拍照相关的功能,包括Temperature和 Acquisition Set,Start Exposure,Stop Exposure,Cooling,Script这几个子功能。
图3 Camera Tab
Debug Tab主要包含一些并不常用的与相机故障诊断相关的功能:包括Voltage,Analog Power,Set Voltage,ResetShutter这几个子功能。
图4 Debug Tab
位于标签栏下方的部分是用于显示拍摄得到的图像的,我们称它为工作区 Work space
。Work space允许同时显示多个图片。
图5 workspace
在整个GUI底部的蓝色bar是状态栏Status Bar,这里将实时地显示冷热端温度和其他几个重要状态量。
图6 status bar
除了这些部分之外,如果点击左上角的File按钮,将会弹出文件管理器 File Manager。File Manager主要包含一系列的与打开文件、保存文件相关的功能。
图六 File Manager
# Camera Tab 相机控制标签
从左至右分别为 温度读出设置、配置、开始曝光、停止曝光、制冷、脚本、对齐、设备信息按钮。
- 温度读出设置按钮可以配置温度轮询的频率,点击此按钮后在左下角状态栏中显示轮询状态的位置会显示轮询的频率。轮询频率会在8秒一次/4秒一次/2秒一次/不轮询之间切换。
- 点击配置按钮可以呼出相机读出配置对话框
- 点击开始曝光按钮,相机会开始曝光。此时在状态栏会显示此次曝光的进度。
- 在相机处于曝光状态时,点击停止曝光按钮,这次曝光将会停止。
- 点击制冷按钮,可以切换相机制冷/不制冷状态。
- 点击脚本按钮,可以呼出使用脚本控制曝光的功能。
- 点击对齐按钮,可以是相机进行一系列调整从而保证在不同温度下的曝光结果都是正确的。当相机通过制冷功能降温/升温到新的温度时,第一次曝光可能会出现错误。此时可以点击对齐按钮进行调整。
- 点击设备信息按钮,可以查看当前设备的序列号、软件逻辑和逻辑版本。
######## Acquisition Set Window 相机读出配置窗口
图七 相机读出配置窗口
- 左侧的Exposure组包含的是与曝光相关的配置:曝光时间按0.001S步进,最低可以设为0(0秒曝光),最长可以设置为3600秒,即一个小时。
- 出图模式可以配置为LDR_LOW,LDR_HIGH,HDR,LDR_HIGH_LOW,他们的含义分别是:
- LDR_LOW:低动态范围低读出增益模式
- LDR_HIGH:低动态范围高度出增益模式
- HDR: 高动态范围模式
- LDR_HIGH_LOW:低动态范围、高低增益同时读出模式,此时每次曝光会出两张图
- 触发模式可以配置为Internal、External和 Time,他们分别表示:
- Internal:基本的利用内部电路触发
- External:使用外出发引脚进行触发
- Time:基于时间的触发,需要配合GPS使用
- 多张模式用于配置连拍,点击左侧的勾选框可以是设备处于连拍模式,右侧的Spinbox可以配置连拍张数。注意如果左侧的勾选框没有勾选,即使当右侧连拍张数不为1时,也会进行单张拍摄。
- 连拍间隔spinbox可以修改连拍模式时每两次拍摄之间的的间隔时间,步进0.1S
- 低暗电流勾选框可以配置相机是否使用低暗电流模式。
- 高增益通道、低增益通道的增益具体数值可由左下角的Spbinbox配置。注意这两个增益值是离散的。
- ROI设置可以手动设置ROI的范围,分别表示起始行、宽度、起始列、高度。
- BIN配置可以使相机读出2X2的BIN模式
- Thermo组包含的与相机制冷相关的配置
- 风扇转速可以配置为0、1、2、3四个挡位。0档表示风扇关闭,1、2、3档风扇转速依次加快
- 制冷温度用于配置制冷目标温度,步进1摄氏度
# Workspace 工作区
图八 工作区
- 工作区用于显示当前拍摄的图片。
- 每次点击开始曝光后,如果曝光成功,工作区将会关闭当前图片并显示新的一张图片
- 进行滚轮放缩操作可以方便的设置ROI
- 进行连拍时,工作区不显示图片
# Status Bar 状态栏
图九 状态栏
- 状态栏的左侧会显示当前更新冷热端温度的频率和状态
- 状态栏中间的两个小浮窗可以显示冷热端当前的温度
# File Manager 文件管理器
文件管理器包含 打开文件、保存文件、另存文件 的功能。
# 三. ADUstc@AreaDetector
类UNIX系统下的分布式的、支持网络的高性能CCD控制器
WIP