[关闭]
@Emptyset 2018-08-12T09:03:41.000000Z 字数 6021 阅读 1433

基于树莓派+INDI协议的开源分布式共享天文台提议

共享天文


  1. 跨平台的软件栈:基于树莓派+INDI驱动。TODO:
    • pythonic的sdk
    • python开源开发者生态:当共享天文向全时域专业工作者延伸的时候。
  2. 共享天文: 任何一处小型天文台/天文设备可以通过接上星际探索订制的树莓派来成为共享天文的设备,并且获得收益分成。
  3. 利用GAN(生成对抗网络),迁移学习Transfer learning,尝试进行摄影图像端到端的AI后期处理
  4. 数据集:
    • 开放天文图片数据集,数据集都是,用于
      • 业余发现:例如超新星的业余发现就依赖人工标注的已知超新星图片数据,CNN+LSTM
      • 图像处理:如上述3,但对数据集的要求比较高,可以尝试Data Augmentation
      • 其他可用于机器学习研究的数据集
      • 强化学习:温度控制系统/自动调焦等
  5. 【TODO】:引入区块链进行图片数据存储(例如ipfs)与摄影作品版权保护

INDI的通用架构

  1. INDI Client 1 ----| |---- INDI Driver A ---- Dev X
  2. | |
  3. INDI Client 2 ----| |---- INDI Driver B ---- Dev Y
  4. | | |
  5. ... |--- indiserver ---| |-- Dev Z
  6. | |
  7. | |
  8. INDI Client n ----| |---- INDI Driver C ---- Dev T

Client连接Server CCD模拟器拍摄Vega的官方Demo

  1. import PyIndi
  2. import time
  3. import sys
  4. import threading
  5. class IndiClient(PyIndi.BaseClient):
  6. def __init__(self):
  7. super(IndiClient, self).__init__()
  8. def newDevice(self, d):
  9. pass
  10. def newProperty(self, p):
  11. pass
  12. def removeProperty(self, p):
  13. pass
  14. def newBLOB(self, bp):
  15. global blobEvent
  16. print("new BLOB ", bp.name)
  17. blobEvent.set()
  18. pass
  19. def newSwitch(self, svp):
  20. pass
  21. def newNumber(self, nvp):
  22. pass
  23. def newText(self, tvp):
  24. pass
  25. def newLight(self, lvp):
  26. pass
  27. def newMessage(self, d, m):
  28. pass
  29. def serverConnected(self):
  30. pass
  31. def serverDisconnected(self, code):
  32. pass
  33. # connect the server
  34. indiclient=IndiClient()
  35. indiclient.setServer("localhost",7624)
  36. if (not(indiclient.connectServer())):
  37. print("No indiserver running on "+indiclient.getHost()+":"+str(indiclient.getPort())+" - Try to run")
  38. print(" indiserver indi_simulator_telescope indi_simulator_ccd")
  39. sys.exit(1)
  40. # connect the scope
  41. telescope="Telescope Simulator"
  42. device_telescope=None
  43. telescope_connect=None
  44. # get the telescope device
  45. device_telescope=indiclient.getDevice(telescope)
  46. while not(device_telescope):
  47. time.sleep(0.5)
  48. device_telescope=indiclient.getDevice(telescope)
  49. # wait CONNECTION property be defined for telescope
  50. telescope_connect=device_telescope.getSwitch("CONNECTION")
  51. while not(telescope_connect):
  52. time.sleep(0.5)
  53. telescope_connect=device_telescope.getSwitch("CONNECTION")
  54. # if the telescope device is not connected, we do connect it
  55. if not(device_telescope.isConnected()):
  56. # Property vectors are mapped to iterable Python objects
  57. # Hence we can access each element of the vector using Python indexing
  58. # each element of the "CONNECTION" vector is a ISwitch
  59. telescope_connect[0].s=PyIndi.ISS_ON # the "CONNECT" switch
  60. telescope_connect[1].s=PyIndi.ISS_OFF # the "DISCONNECT" switch
  61. indiclient.sendNewSwitch(telescope_connect) # send this new value to the device
  62. # Now let's make a goto to vega
  63. # Beware that ra/dec are in decimal hours/degrees
  64. vega={'ra': (279.23473479 * 24.0)/360.0, 'dec': +38.78368896 }
  65. # We want to set the ON_COORD_SET switch to engage tracking after goto
  66. # device.getSwitch is a helper to retrieve a property vector
  67. telescope_on_coord_set=device_telescope.getSwitch("ON_COORD_SET")
  68. while not(telescope_on_coord_set):
  69. time.sleep(0.5)
  70. telescope_on_coord_set=device_telescope.getSwitch("ON_COORD_SET")
  71. # the order below is defined in the property vector, look at the standard Properties page
  72. # or enumerate them in the Python shell when you're developing your program
  73. telescope_on_coord_set[0].s=PyIndi.ISS_ON # TRACK
  74. telescope_on_coord_set[1].s=PyIndi.ISS_OFF # SLEW
  75. telescope_on_coord_set[2].s=PyIndi.ISS_OFF # SYNC
  76. indiclient.sendNewSwitch(telescope_on_coord_set)
  77. # We set the desired coordinates
  78. telescope_radec=device_telescope.getNumber("EQUATORIAL_EOD_COORD")
  79. while not(telescope_radec):
  80. time.sleep(0.5)
  81. telescope_radec=device_telescope.getNumber("EQUATORIAL_EOD_COORD")
  82. telescope_radec[0].value=vega['ra']
  83. telescope_radec[1].value=vega['dec']
  84. indiclient.sendNewNumber(telescope_radec)
  85. # and wait for the scope has finished moving
  86. while (telescope_radec.s==PyIndi.IPS_BUSY):
  87. print("Scope Moving ", telescope_radec[0].value, telescope_radec[1].value)
  88. time.sleep(2)
  89. # Let's take some pictures
  90. ccd="CCD Simulator"
  91. device_ccd=indiclient.getDevice(ccd)
  92. while not(device_ccd):
  93. time.sleep(0.5)
  94. device_ccd=indiclient.getDevice(ccd)
  95. ccd_connect=device_ccd.getSwitch("CONNECTION")
  96. while not(ccd_connect):
  97. time.sleep(0.5)
  98. ccd_connect=device_ccd.getSwitch("CONNECTION")
  99. if not(device_ccd.isConnected()):
  100. ccd_connect[0].s=PyIndi.ISS_ON # the "CONNECT" switch
  101. ccd_connect[1].s=PyIndi.ISS_OFF # the "DISCONNECT" switch
  102. indiclient.sendNewSwitch(ccd_connect)
  103. ccd_exposure=device_ccd.getNumber("CCD_EXPOSURE")
  104. while not(ccd_exposure):
  105. time.sleep(0.5)
  106. ccd_exposure=device_ccd.getNumber("CCD_EXPOSURE")
  107. # Ensure the CCD simulator snoops the telescope simulator
  108. # otherwise you may not have a picture of vega
  109. ccd_active_devices=device_ccd.getText("ACTIVE_DEVICES")
  110. while not(ccd_active_devices):
  111. time.sleep(0.5)
  112. ccd_active_devices=device_ccd.getText("ACTIVE_DEVICES")
  113. ccd_active_devices[0].text="Telescope Simulator"
  114. indiclient.sendNewText(ccd_active_devices)
  115. # we should inform the indi server that we want to receive the
  116. # "CCD1" blob from this device
  117. indiclient.setBLOBMode(PyIndi.B_ALSO, ccd, "CCD1")
  118. ccd_ccd1=device_ccd.getBLOB("CCD1")
  119. while not(ccd_ccd1):
  120. time.sleep(0.5)
  121. ccd_ccd1=device_ccd.getBLOB("CCD1")
  122. # a list of our exposure times
  123. exposures=[1.0, 5.0]
  124. # we use here the threading.Event facility of Python
  125. # we define an event for newBlob event
  126. blobEvent=threading.Event()
  127. blobEvent.clear()
  128. i=0
  129. ccd_exposure[0].value=exposures[i]
  130. indiclient.sendNewNumber(ccd_exposure)
  131. while (i < len(exposures)):
  132. # wait for the ith exposure
  133. blobEvent.wait()
  134. # we can start immediately the next one
  135. if (i + 1 < len(exposures)):
  136. ccd_exposure[0].value=exposures[i+1]
  137. blobEvent.clear()
  138. indiclient.sendNewNumber(ccd_exposure)
  139. # and meanwhile process the received one
  140. for blob in ccd_ccd1:
  141. print("name: ", blob.name," size: ", blob.size," format: ", blob.format)
  142. # pyindi-client adds a getblobdata() method to IBLOB item
  143. # for accessing the contents of the blob, which is a bytearray in Python
  144. fits=blob.getblobdata()
  145. print("fits data type: ", type(fits))
  146. # here you may use astropy.io.fits to access the fits data
  147. # and perform some computations while the ccd is exposing
  148. # but this is outside the scope of this tutorial
  149. i+=1

A user-friendly pythonic API for public users

  1. xtelescope_server
  1. from xtelescope import Client
  2. client = Client(server="ip_address_of_the_server", port=1011)
  3. # A User authentication based on APP_SECRET, SECRET_KEY might be required
  4. # client.auth()
  5. telescopes = client.available_telescopes()
  6. my_device = telescopes["XP1"]
  7. my_device.auto_focus() # 自动对焦
  8. my_device.goto(object="vega").track()
  9. # vega={'ra': (279.23473479 * 24.0)/360.0, 'dec': +38.78368896 }
  10. # my_device.goto(coord=vega)
  11. fits = my_device.capture() # 拍摄
  12. my_device.status # 查看设备状态以dict/json形式返回
  13. # 一键处理
  14. from xtelescope import openastro
  15. image = openastro.galaxyGAN(fits)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注