cgse 2024.7.0__py3-none-any.whl → 2025.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (664) hide show
  1. README.md +27 -0
  2. bump.py +85 -0
  3. cgse-2025.0.1.dist-info/METADATA +38 -0
  4. cgse-2025.0.1.dist-info/RECORD +5 -0
  5. {cgse-2024.7.0.dist-info → cgse-2025.0.1.dist-info}/WHEEL +1 -2
  6. cgse-2024.7.0.dist-info/COPYING +0 -674
  7. cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
  8. cgse-2024.7.0.dist-info/METADATA +0 -144
  9. cgse-2024.7.0.dist-info/RECORD +0 -660
  10. cgse-2024.7.0.dist-info/entry_points.txt +0 -75
  11. cgse-2024.7.0.dist-info/top_level.txt +0 -2
  12. egse/__init__.py +0 -12
  13. egse/__main__.py +0 -32
  14. egse/aeu/aeu.py +0 -5238
  15. egse/aeu/aeu_awg.yaml +0 -265
  16. egse/aeu/aeu_crio.yaml +0 -273
  17. egse/aeu/aeu_cs.py +0 -627
  18. egse/aeu/aeu_devif.py +0 -321
  19. egse/aeu/aeu_main_ui.py +0 -903
  20. egse/aeu/aeu_metrics.py +0 -131
  21. egse/aeu/aeu_protocol.py +0 -463
  22. egse/aeu/aeu_psu.yaml +0 -204
  23. egse/aeu/aeu_ui.py +0 -873
  24. egse/aeu/arbdata/FccdRead.arb +0 -2
  25. egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
  26. egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
  27. egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
  28. egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
  29. egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
  30. egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
  31. egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
  32. egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
  33. egse/aeu/arbdata/ccdRead25.arb +0 -2
  34. egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
  35. egse/aeu/arbdata/ccdRead31_25.arb +0 -2
  36. egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
  37. egse/aeu/arbdata/ccdRead37_50.arb +0 -2
  38. egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
  39. egse/aeu/arbdata/ccdRead43_75.arb +0 -2
  40. egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
  41. egse/aeu/arbdata/ccdRead50.arb +0 -2
  42. egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
  43. egse/alert/__init__.py +0 -1049
  44. egse/alert/alertman.yaml +0 -37
  45. egse/alert/alertman_cs.py +0 -233
  46. egse/alert/alertman_ui.py +0 -600
  47. egse/alert/gsm/beaglebone.py +0 -138
  48. egse/alert/gsm/beaglebone.yaml +0 -51
  49. egse/alert/gsm/beaglebone_cs.py +0 -108
  50. egse/alert/gsm/beaglebone_devif.py +0 -122
  51. egse/alert/gsm/beaglebone_protocol.py +0 -46
  52. egse/bits.py +0 -318
  53. egse/camera.py +0 -44
  54. egse/collimator/__init__.py +0 -0
  55. egse/collimator/fcul/__init__.py +0 -0
  56. egse/collimator/fcul/ogse.py +0 -1077
  57. egse/collimator/fcul/ogse.yaml +0 -14
  58. egse/collimator/fcul/ogse_cs.py +0 -154
  59. egse/collimator/fcul/ogse_devif.py +0 -358
  60. egse/collimator/fcul/ogse_protocol.py +0 -132
  61. egse/collimator/fcul/ogse_sim.py +0 -431
  62. egse/collimator/fcul/ogse_ui.py +0 -1108
  63. egse/command.py +0 -699
  64. egse/config.py +0 -410
  65. egse/confman/__init__.py +0 -1058
  66. egse/confman/confman.yaml +0 -70
  67. egse/confman/confman_cs.py +0 -240
  68. egse/confman/confman_ui.py +0 -381
  69. egse/confman/setup_ui.py +0 -565
  70. egse/control.py +0 -632
  71. egse/coordinates/__init__.py +0 -534
  72. egse/coordinates/avoidance.py +0 -100
  73. egse/coordinates/cslmodel.py +0 -127
  74. egse/coordinates/laser_tracker_to_dict.py +0 -122
  75. egse/coordinates/point.py +0 -707
  76. egse/coordinates/pyplot.py +0 -194
  77. egse/coordinates/referenceFrame.py +0 -1279
  78. egse/coordinates/refmodel.py +0 -737
  79. egse/coordinates/rotationMatrix.py +0 -85
  80. egse/coordinates/transform3d_addon.py +0 -419
  81. egse/csl/__init__.py +0 -50
  82. egse/csl/commanding.py +0 -78
  83. egse/csl/icons/hexapod-connected-selected.svg +0 -30
  84. egse/csl/icons/hexapod-connected.svg +0 -30
  85. egse/csl/icons/hexapod-homing-selected.svg +0 -68
  86. egse/csl/icons/hexapod-homing.svg +0 -68
  87. egse/csl/icons/hexapod-retract-selected.svg +0 -56
  88. egse/csl/icons/hexapod-retract.svg +0 -51
  89. egse/csl/icons/hexapod-zero-selected.svg +0 -56
  90. egse/csl/icons/hexapod-zero.svg +0 -56
  91. egse/csl/icons/logo-puna.svg +0 -92
  92. egse/csl/icons/stop.svg +0 -1
  93. egse/csl/initialisation.py +0 -102
  94. egse/csl/mech_pos_settings.yaml +0 -18
  95. egse/das.py +0 -1240
  96. egse/das.yaml +0 -7
  97. egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
  98. egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
  99. egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
  100. egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
  101. egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
  102. egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
  103. egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
  104. egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
  105. egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
  106. egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
  107. egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
  108. egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
  109. egse/decorators.py +0 -514
  110. egse/device.py +0 -269
  111. egse/dpu/__init__.py +0 -2698
  112. egse/dpu/ccd_ui.py +0 -514
  113. egse/dpu/dpu.py +0 -783
  114. egse/dpu/dpu.yaml +0 -153
  115. egse/dpu/dpu_cs.py +0 -272
  116. egse/dpu/dpu_ui.py +0 -671
  117. egse/dpu/fitsgen.py +0 -2096
  118. egse/dpu/fitsgen_ui.py +0 -399
  119. egse/dpu/hdf5_model.py +0 -332
  120. egse/dpu/hdf5_ui.py +0 -277
  121. egse/dpu/hdf5_viewer.py +0 -506
  122. egse/dpu/hk_ui.py +0 -468
  123. egse/dpu_commands.py +0 -81
  124. egse/dsi/__init__.py +0 -33
  125. egse/dsi/_libesl.py +0 -232
  126. egse/dsi/constants.py +0 -296
  127. egse/dsi/esl.py +0 -630
  128. egse/dsi/rmap.py +0 -444
  129. egse/dsi/rmapci.py +0 -39
  130. egse/dsi/spw.py +0 -335
  131. egse/dsi/spw_state.py +0 -29
  132. egse/dummy.py +0 -318
  133. egse/dyndummy.py +0 -179
  134. egse/env.py +0 -278
  135. egse/exceptions.py +0 -88
  136. egse/fdir/__init__.py +0 -26
  137. egse/fdir/fdir_manager.py +0 -85
  138. egse/fdir/fdir_manager.yaml +0 -37
  139. egse/fdir/fdir_manager_controller.py +0 -136
  140. egse/fdir/fdir_manager_cs.py +0 -164
  141. egse/fdir/fdir_manager_interface.py +0 -15
  142. egse/fdir/fdir_remote.py +0 -73
  143. egse/fdir/fdir_remote.yaml +0 -30
  144. egse/fdir/fdir_remote_controller.py +0 -30
  145. egse/fdir/fdir_remote_cs.py +0 -94
  146. egse/fdir/fdir_remote_interface.py +0 -9
  147. egse/fdir/fdir_remote_popup.py +0 -26
  148. egse/fee/__init__.py +0 -106
  149. egse/fee/f_fee_register.yaml +0 -43
  150. egse/fee/feesim.py +0 -914
  151. egse/fee/n_fee_hk.py +0 -768
  152. egse/fee/nfee.py +0 -188
  153. egse/filterwheel/__init__.py +0 -4
  154. egse/filterwheel/eksma/__init__.py +0 -49
  155. egse/filterwheel/eksma/fw8smc4.py +0 -657
  156. egse/filterwheel/eksma/fw8smc4.yaml +0 -121
  157. egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
  158. egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
  159. egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
  160. egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
  161. egse/filterwheel/eksma/fw8smc5.py +0 -115
  162. egse/filterwheel/eksma/fw8smc5.yaml +0 -105
  163. egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
  164. egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
  165. egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
  166. egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
  167. egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
  168. egse/filterwheel/eksma/testpythonfw.py +0 -215
  169. egse/fov/__init__.py +0 -65
  170. egse/fov/fov_hk.py +0 -710
  171. egse/fov/fov_ui.py +0 -859
  172. egse/fov/fov_ui_controller.py +0 -140
  173. egse/fov/fov_ui_model.py +0 -200
  174. egse/fov/fov_ui_view.py +0 -345
  175. egse/gimbal/__init__.py +0 -32
  176. egse/gimbal/symetrie/__init__.py +0 -26
  177. egse/gimbal/symetrie/alpha.py +0 -586
  178. egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
  179. egse/gimbal/symetrie/gimbal.py +0 -877
  180. egse/gimbal/symetrie/gimbal.yaml +0 -168
  181. egse/gimbal/symetrie/gimbal_cs.py +0 -183
  182. egse/gimbal/symetrie/gimbal_protocol.py +0 -138
  183. egse/gimbal/symetrie/gimbal_ui.py +0 -361
  184. egse/gimbal/symetrie/pmac.py +0 -1006
  185. egse/gimbal/symetrie/pmac_regex.py +0 -83
  186. egse/graph.py +0 -132
  187. egse/gui/__init__.py +0 -47
  188. egse/gui/buttons.py +0 -378
  189. egse/gui/focalplane.py +0 -1285
  190. egse/gui/formatter.py +0 -10
  191. egse/gui/led.py +0 -162
  192. egse/gui/limitswitch.py +0 -143
  193. egse/gui/mechanisms.py +0 -587
  194. egse/gui/states.py +0 -148
  195. egse/gui/stripchart.py +0 -729
  196. egse/gui/styles.qss +0 -48
  197. egse/gui/switch.py +0 -112
  198. egse/h5.py +0 -274
  199. egse/help/__init__.py +0 -0
  200. egse/help/help_ui.py +0 -126
  201. egse/hexapod/__init__.py +0 -32
  202. egse/hexapod/symetrie/__init__.py +0 -137
  203. egse/hexapod/symetrie/alpha.py +0 -874
  204. egse/hexapod/symetrie/dynalpha.py +0 -1387
  205. egse/hexapod/symetrie/hexapod_ui.py +0 -1516
  206. egse/hexapod/symetrie/pmac.py +0 -1010
  207. egse/hexapod/symetrie/pmac_regex.py +0 -83
  208. egse/hexapod/symetrie/puna.py +0 -1167
  209. egse/hexapod/symetrie/puna.yaml +0 -193
  210. egse/hexapod/symetrie/puna_cs.py +0 -195
  211. egse/hexapod/symetrie/puna_protocol.py +0 -134
  212. egse/hexapod/symetrie/puna_ui.py +0 -433
  213. egse/hexapod/symetrie/punaplus.py +0 -107
  214. egse/hexapod/symetrie/zonda.py +0 -872
  215. egse/hexapod/symetrie/zonda.yaml +0 -337
  216. egse/hexapod/symetrie/zonda_cs.py +0 -172
  217. egse/hexapod/symetrie/zonda_devif.py +0 -414
  218. egse/hexapod/symetrie/zonda_protocol.py +0 -123
  219. egse/hexapod/symetrie/zonda_ui.py +0 -449
  220. egse/hk.py +0 -791
  221. egse/icons/aeu-cs-start.svg +0 -117
  222. egse/icons/aeu-cs-stop.svg +0 -118
  223. egse/icons/aeu-cs.svg +0 -107
  224. egse/icons/aeu_cs-started.svg +0 -112
  225. egse/icons/aeu_cs-stopped.svg +0 -112
  226. egse/icons/aeu_cs.svg +0 -55
  227. egse/icons/alert.svg +0 -1
  228. egse/icons/arrow-double-left.png +0 -0
  229. egse/icons/arrow-double-right.png +0 -0
  230. egse/icons/arrow-up.svg +0 -11
  231. egse/icons/backward.svg +0 -1
  232. egse/icons/busy.svg +0 -1
  233. egse/icons/cleaning.svg +0 -115
  234. egse/icons/color-scheme.svg +0 -1
  235. egse/icons/cs-connected-alert.svg +0 -91
  236. egse/icons/cs-connected-disabled.svg +0 -43
  237. egse/icons/cs-connected.svg +0 -89
  238. egse/icons/cs-not-connected.svg +0 -44
  239. egse/icons/double-left-arrow.svg +0 -1
  240. egse/icons/double-right-arrow.svg +0 -1
  241. egse/icons/erase-disabled.svg +0 -19
  242. egse/icons/erase.svg +0 -59
  243. egse/icons/fitsgen-start.svg +0 -47
  244. egse/icons/fitsgen-stop.svg +0 -48
  245. egse/icons/fitsgen.svg +0 -1
  246. egse/icons/forward.svg +0 -1
  247. egse/icons/fov-hk-start.svg +0 -33
  248. egse/icons/fov-hk-stop.svg +0 -37
  249. egse/icons/fov-hk.svg +0 -1
  250. egse/icons/front-desk.svg +0 -1
  251. egse/icons/home-actioned.svg +0 -15
  252. egse/icons/home-disabled.svg +0 -15
  253. egse/icons/home.svg +0 -13
  254. egse/icons/info.svg +0 -1
  255. egse/icons/invalid.png +0 -0
  256. egse/icons/led-green.svg +0 -20
  257. egse/icons/led-grey.svg +0 -20
  258. egse/icons/led-orange.svg +0 -20
  259. egse/icons/led-red.svg +0 -20
  260. egse/icons/led-square-green.svg +0 -134
  261. egse/icons/led-square-grey.svg +0 -134
  262. egse/icons/led-square-orange.svg +0 -134
  263. egse/icons/led-square-red.svg +0 -134
  264. egse/icons/limit-switch-all-green.svg +0 -115
  265. egse/icons/limit-switch-all-red.svg +0 -117
  266. egse/icons/limit-switch-el+.svg +0 -116
  267. egse/icons/limit-switch-el-.svg +0 -117
  268. egse/icons/location-marker.svg +0 -1
  269. egse/icons/logo-dpu.svg +0 -48
  270. egse/icons/logo-gimbal.svg +0 -112
  271. egse/icons/logo-huber.svg +0 -23
  272. egse/icons/logo-ogse.svg +0 -31
  273. egse/icons/logo-puna.svg +0 -92
  274. egse/icons/logo-tcs.svg +0 -29
  275. egse/icons/logo-zonda.svg +0 -66
  276. egse/icons/maximize.svg +0 -1
  277. egse/icons/meter.svg +0 -1
  278. egse/icons/more.svg +0 -45
  279. egse/icons/n-fee-hk-start.svg +0 -24
  280. egse/icons/n-fee-hk-stop.svg +0 -25
  281. egse/icons/n-fee-hk.svg +0 -83
  282. egse/icons/observing-off.svg +0 -46
  283. egse/icons/observing-on.svg +0 -46
  284. egse/icons/open-document-hdf5.png +0 -0
  285. egse/icons/open-document-hdf5.svg +0 -21
  286. egse/icons/ops-mode.svg +0 -1
  287. egse/icons/play-green.svg +0 -17
  288. egse/icons/plugged-disabled.svg +0 -27
  289. egse/icons/plugged.svg +0 -21
  290. egse/icons/pm_ui.svg +0 -1
  291. egse/icons/power-button-green.svg +0 -27
  292. egse/icons/power-button-red.svg +0 -27
  293. egse/icons/power-button.svg +0 -27
  294. egse/icons/radar.svg +0 -1
  295. egse/icons/radioactive.svg +0 -2
  296. egse/icons/reload.svg +0 -1
  297. egse/icons/remote-control-off.svg +0 -28
  298. egse/icons/remote-control-on.svg +0 -28
  299. egse/icons/repeat-blue.svg +0 -15
  300. egse/icons/repeat.svg +0 -1
  301. egse/icons/settings.svg +0 -1
  302. egse/icons/shrink.svg +0 -1
  303. egse/icons/shutter.svg +0 -1
  304. egse/icons/sign-off.svg +0 -1
  305. egse/icons/sign-on.svg +0 -1
  306. egse/icons/sim-mode.svg +0 -1
  307. egse/icons/small-buttons-go.svg +0 -20
  308. egse/icons/small-buttons-minus.svg +0 -51
  309. egse/icons/small-buttons-plus.svg +0 -51
  310. egse/icons/sponge.svg +0 -220
  311. egse/icons/start-button-disabled.svg +0 -84
  312. egse/icons/start-button.svg +0 -50
  313. egse/icons/stop-button-disabled.svg +0 -84
  314. egse/icons/stop-button.svg +0 -50
  315. egse/icons/stop-red.svg +0 -17
  316. egse/icons/stop.svg +0 -1
  317. egse/icons/switch-disabled-square.svg +0 -87
  318. egse/icons/switch-disabled.svg +0 -15
  319. egse/icons/switch-off-square.svg +0 -87
  320. egse/icons/switch-off.svg +0 -72
  321. egse/icons/switch-on-square.svg +0 -87
  322. egse/icons/switch-on.svg +0 -61
  323. egse/icons/temperature-control.svg +0 -44
  324. egse/icons/th_ui_logo.svg +0 -1
  325. egse/icons/unplugged.svg +0 -23
  326. egse/icons/unvalid.png +0 -0
  327. egse/icons/user-interface.svg +0 -1
  328. egse/icons/vacuum.svg +0 -1
  329. egse/icons/valid.png +0 -0
  330. egse/icons/zoom-to-pixel-dark.svg +0 -64
  331. egse/icons/zoom-to-pixel-white.svg +0 -36
  332. egse/images/big-rotation-stage.png +0 -0
  333. egse/images/connected-100.png +0 -0
  334. egse/images/cross.svg +0 -6
  335. egse/images/disconnected-100.png +0 -0
  336. egse/images/gui-icon.png +0 -0
  337. egse/images/home.svg +0 -6
  338. egse/images/info-icon.png +0 -0
  339. egse/images/led-black.svg +0 -89
  340. egse/images/led-green.svg +0 -85
  341. egse/images/led-orange.svg +0 -85
  342. egse/images/led-red.svg +0 -85
  343. egse/images/load-icon.png +0 -0
  344. egse/images/load-setup.png +0 -0
  345. egse/images/load.png +0 -0
  346. egse/images/pause.png +0 -0
  347. egse/images/play-button.svg +0 -8
  348. egse/images/play.png +0 -0
  349. egse/images/process-status.png +0 -0
  350. egse/images/restart.png +0 -0
  351. egse/images/search.png +0 -0
  352. egse/images/sma.png +0 -0
  353. egse/images/start.png +0 -0
  354. egse/images/stop-button.svg +0 -8
  355. egse/images/stop.png +0 -0
  356. egse/images/switch-off.svg +0 -48
  357. egse/images/switch-on.svg +0 -48
  358. egse/images/undo.png +0 -0
  359. egse/images/update-button.svg +0 -11
  360. egse/imageviewer/exposureselection.py +0 -475
  361. egse/imageviewer/imageviewer.py +0 -198
  362. egse/imageviewer/matchfocalplane.py +0 -179
  363. egse/imageviewer/subfieldposition.py +0 -133
  364. egse/lampcontrol/__init__.py +0 -4
  365. egse/lampcontrol/beaglebone/beaglebone.py +0 -178
  366. egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
  367. egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
  368. egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
  369. egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
  370. egse/lampcontrol/energetiq/__init__.py +0 -22
  371. egse/lampcontrol/energetiq/eq99.yaml +0 -98
  372. egse/lampcontrol/energetiq/lampEQ99.py +0 -283
  373. egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
  374. egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
  375. egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
  376. egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
  377. egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
  378. egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
  379. egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
  380. egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
  381. egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
  382. egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
  383. egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
  384. egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
  385. egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
  386. egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
  387. egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
  388. egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
  389. egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
  390. egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
  391. egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
  392. egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
  393. egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
  394. egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
  395. egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
  396. egse/lib/ximc/libximc.framework/libbindy.so +0 -0
  397. egse/lib/ximc/libximc.framework/libximc +0 -0
  398. egse/lib/ximc/libximc.framework/libximc.so +0 -0
  399. egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
  400. egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
  401. egse/lib/ximc/pyximc.py +0 -922
  402. egse/listener.py +0 -179
  403. egse/logger/__init__.py +0 -243
  404. egse/logger/log_cs.py +0 -321
  405. egse/metrics.py +0 -102
  406. egse/mixin.py +0 -464
  407. egse/monitoring.py +0 -95
  408. egse/ni/alarms/__init__.py +0 -26
  409. egse/ni/alarms/cdaq9375.py +0 -300
  410. egse/ni/alarms/cdaq9375.yaml +0 -89
  411. egse/ni/alarms/cdaq9375_cs.py +0 -130
  412. egse/ni/alarms/cdaq9375_devif.py +0 -183
  413. egse/ni/alarms/cdaq9375_protocol.py +0 -48
  414. egse/obs_inspection.py +0 -165
  415. egse/observer.py +0 -41
  416. egse/obsid.py +0 -163
  417. egse/powermeter/__init__.py +0 -0
  418. egse/powermeter/ni/__init__.py +0 -38
  419. egse/powermeter/ni/cdaq9184.py +0 -224
  420. egse/powermeter/ni/cdaq9184.yaml +0 -73
  421. egse/powermeter/ni/cdaq9184_cs.py +0 -130
  422. egse/powermeter/ni/cdaq9184_devif.py +0 -201
  423. egse/powermeter/ni/cdaq9184_protocol.py +0 -48
  424. egse/powermeter/ni/cdaq9184_ui.py +0 -544
  425. egse/powermeter/thorlabs/__init__.py +0 -25
  426. egse/powermeter/thorlabs/pm100a.py +0 -380
  427. egse/powermeter/thorlabs/pm100a.yaml +0 -132
  428. egse/powermeter/thorlabs/pm100a_cs.py +0 -136
  429. egse/powermeter/thorlabs/pm100a_devif.py +0 -127
  430. egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
  431. egse/powermeter/thorlabs/pm100a_ui.py +0 -725
  432. egse/process.py +0 -451
  433. egse/procman/__init__.py +0 -834
  434. egse/procman/cannot_start_process_popup.py +0 -43
  435. egse/procman/procman.yaml +0 -49
  436. egse/procman/procman_cs.py +0 -201
  437. egse/procman/procman_ui.py +0 -2081
  438. egse/protocol.py +0 -605
  439. egse/proxy.py +0 -531
  440. egse/randomwalk.py +0 -140
  441. egse/reg.py +0 -585
  442. egse/reload.py +0 -122
  443. egse/reprocess.py +0 -693
  444. egse/resource.py +0 -333
  445. egse/rmap.py +0 -406
  446. egse/rst.py +0 -135
  447. egse/search.py +0 -182
  448. egse/serialdevice.py +0 -190
  449. egse/services.py +0 -247
  450. egse/services.yaml +0 -68
  451. egse/settings.py +0 -379
  452. egse/settings.yaml +0 -980
  453. egse/setup.py +0 -1181
  454. egse/shutter/__init__.py +0 -0
  455. egse/shutter/thorlabs/__init__.py +0 -19
  456. egse/shutter/thorlabs/ksc101.py +0 -205
  457. egse/shutter/thorlabs/ksc101.yaml +0 -105
  458. egse/shutter/thorlabs/ksc101_cs.py +0 -136
  459. egse/shutter/thorlabs/ksc101_devif.py +0 -201
  460. egse/shutter/thorlabs/ksc101_protocol.py +0 -71
  461. egse/shutter/thorlabs/ksc101_ui.py +0 -548
  462. egse/shutter/thorlabs/sc10.py +0 -82
  463. egse/shutter/thorlabs/sc10.yaml +0 -52
  464. egse/shutter/thorlabs/sc10_controller.py +0 -81
  465. egse/shutter/thorlabs/sc10_cs.py +0 -108
  466. egse/shutter/thorlabs/sc10_interface.py +0 -25
  467. egse/shutter/thorlabs/sc10_simulator.py +0 -30
  468. egse/simulator.py +0 -41
  469. egse/slack.py +0 -61
  470. egse/socketdevice.py +0 -218
  471. egse/sockets.py +0 -218
  472. egse/spw.py +0 -1401
  473. egse/stages/__init__.py +0 -12
  474. egse/stages/aerotech/ensemble.py +0 -245
  475. egse/stages/aerotech/ensemble.yaml +0 -205
  476. egse/stages/aerotech/ensemble_controller.py +0 -275
  477. egse/stages/aerotech/ensemble_cs.py +0 -110
  478. egse/stages/aerotech/ensemble_interface.py +0 -132
  479. egse/stages/aerotech/ensemble_parameters.py +0 -433
  480. egse/stages/aerotech/ensemble_simulator.py +0 -27
  481. egse/stages/aerotech/mgse_sim.py +0 -188
  482. egse/stages/arun/smd3.py +0 -110
  483. egse/stages/arun/smd3.yaml +0 -68
  484. egse/stages/arun/smd3_controller.py +0 -470
  485. egse/stages/arun/smd3_cs.py +0 -112
  486. egse/stages/arun/smd3_interface.py +0 -53
  487. egse/stages/arun/smd3_simulator.py +0 -27
  488. egse/stages/arun/smd3_stop.py +0 -16
  489. egse/stages/huber/__init__.py +0 -49
  490. egse/stages/huber/smc9300.py +0 -920
  491. egse/stages/huber/smc9300.yaml +0 -63
  492. egse/stages/huber/smc9300_cs.py +0 -178
  493. egse/stages/huber/smc9300_devif.py +0 -345
  494. egse/stages/huber/smc9300_protocol.py +0 -113
  495. egse/stages/huber/smc9300_sim.py +0 -547
  496. egse/stages/huber/smc9300_ui.py +0 -973
  497. egse/state.py +0 -173
  498. egse/statemachine.py +0 -274
  499. egse/storage/__init__.py +0 -1067
  500. egse/storage/persistence.py +0 -2295
  501. egse/storage/storage.yaml +0 -79
  502. egse/storage/storage_cs.py +0 -231
  503. egse/styles/dark.qss +0 -343
  504. egse/styles/default.qss +0 -48
  505. egse/synoptics/__init__.py +0 -417
  506. egse/synoptics/syn.yaml +0 -9
  507. egse/synoptics/syn_cs.py +0 -195
  508. egse/system.py +0 -1611
  509. egse/tcs/__init__.py +0 -14
  510. egse/tcs/tcs.py +0 -879
  511. egse/tcs/tcs.yaml +0 -14
  512. egse/tcs/tcs_cs.py +0 -202
  513. egse/tcs/tcs_devif.py +0 -292
  514. egse/tcs/tcs_protocol.py +0 -180
  515. egse/tcs/tcs_sim.py +0 -177
  516. egse/tcs/tcs_ui.py +0 -543
  517. egse/tdms.py +0 -171
  518. egse/tempcontrol/__init__.py +0 -23
  519. egse/tempcontrol/agilent/agilent34970.py +0 -109
  520. egse/tempcontrol/agilent/agilent34970.yaml +0 -44
  521. egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
  522. egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
  523. egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
  524. egse/tempcontrol/agilent/agilent34972.py +0 -111
  525. egse/tempcontrol/agilent/agilent34972.yaml +0 -44
  526. egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
  527. egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
  528. egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
  529. egse/tempcontrol/beaglebone/beaglebone.py +0 -341
  530. egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
  531. egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
  532. egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
  533. egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
  534. egse/tempcontrol/digalox/digalox.py +0 -115
  535. egse/tempcontrol/digalox/digalox.yaml +0 -36
  536. egse/tempcontrol/digalox/digalox_cs.py +0 -108
  537. egse/tempcontrol/digalox/digalox_protocol.py +0 -56
  538. egse/tempcontrol/keithley/__init__.py +0 -33
  539. egse/tempcontrol/keithley/daq6510.py +0 -662
  540. egse/tempcontrol/keithley/daq6510.yaml +0 -105
  541. egse/tempcontrol/keithley/daq6510_cs.py +0 -163
  542. egse/tempcontrol/keithley/daq6510_devif.py +0 -343
  543. egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
  544. egse/tempcontrol/keithley/daq6510_sim.py +0 -186
  545. egse/tempcontrol/lakeshore/__init__.py +0 -33
  546. egse/tempcontrol/lakeshore/lsci.py +0 -361
  547. egse/tempcontrol/lakeshore/lsci.yaml +0 -162
  548. egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
  549. egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
  550. egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
  551. egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
  552. egse/tempcontrol/ni/__init__.py +0 -0
  553. egse/tempcontrol/spid/spid.py +0 -109
  554. egse/tempcontrol/spid/spid.yaml +0 -81
  555. egse/tempcontrol/spid/spid_controller.py +0 -279
  556. egse/tempcontrol/spid/spid_cs.py +0 -136
  557. egse/tempcontrol/spid/spid_protocol.py +0 -107
  558. egse/tempcontrol/spid/spid_ui.py +0 -723
  559. egse/tempcontrol/srs/__init__.py +0 -22
  560. egse/tempcontrol/srs/ptc10.py +0 -867
  561. egse/tempcontrol/srs/ptc10.yaml +0 -227
  562. egse/tempcontrol/srs/ptc10_cs.py +0 -128
  563. egse/tempcontrol/srs/ptc10_devif.py +0 -116
  564. egse/tempcontrol/srs/ptc10_protocol.py +0 -39
  565. egse/tempcontrol/srs/ptc10_ui.py +0 -906
  566. egse/ups/apc/apc.py +0 -236
  567. egse/ups/apc/apc.yaml +0 -45
  568. egse/ups/apc/apc_cs.py +0 -101
  569. egse/ups/apc/apc_protocol.py +0 -125
  570. egse/user.yaml +0 -7
  571. egse/vacuum/beaglebone/beaglebone.py +0 -149
  572. egse/vacuum/beaglebone/beaglebone.yaml +0 -44
  573. egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
  574. egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
  575. egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
  576. egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
  577. egse/vacuum/instrutech/igm402.py +0 -91
  578. egse/vacuum/instrutech/igm402.yaml +0 -90
  579. egse/vacuum/instrutech/igm402_controller.py +0 -124
  580. egse/vacuum/instrutech/igm402_cs.py +0 -108
  581. egse/vacuum/instrutech/igm402_interface.py +0 -49
  582. egse/vacuum/instrutech/igm402_simulator.py +0 -36
  583. egse/vacuum/keller/kellerBus.py +0 -256
  584. egse/vacuum/keller/leo3.py +0 -100
  585. egse/vacuum/keller/leo3.yaml +0 -38
  586. egse/vacuum/keller/leo3_controller.py +0 -81
  587. egse/vacuum/keller/leo3_cs.py +0 -101
  588. egse/vacuum/keller/leo3_interface.py +0 -33
  589. egse/vacuum/mks/evision.py +0 -86
  590. egse/vacuum/mks/evision.yaml +0 -75
  591. egse/vacuum/mks/evision_cs.py +0 -101
  592. egse/vacuum/mks/evision_devif.py +0 -313
  593. egse/vacuum/mks/evision_interface.py +0 -60
  594. egse/vacuum/mks/evision_simulator.py +0 -24
  595. egse/vacuum/mks/evision_ui.py +0 -701
  596. egse/vacuum/pfeiffer/acp40.py +0 -87
  597. egse/vacuum/pfeiffer/acp40.yaml +0 -60
  598. egse/vacuum/pfeiffer/acp40_controller.py +0 -117
  599. egse/vacuum/pfeiffer/acp40_cs.py +0 -109
  600. egse/vacuum/pfeiffer/acp40_interface.py +0 -40
  601. egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
  602. egse/vacuum/pfeiffer/tc400.py +0 -87
  603. egse/vacuum/pfeiffer/tc400.yaml +0 -83
  604. egse/vacuum/pfeiffer/tc400_controller.py +0 -136
  605. egse/vacuum/pfeiffer/tc400_cs.py +0 -109
  606. egse/vacuum/pfeiffer/tc400_interface.py +0 -70
  607. egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
  608. egse/vacuum/pfeiffer/tpg261.py +0 -80
  609. egse/vacuum/pfeiffer/tpg261.yaml +0 -66
  610. egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
  611. egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
  612. egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
  613. egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
  614. egse/version.py +0 -174
  615. egse/visitedpositions.py +0 -398
  616. egse/windowing.py +0 -213
  617. egse/zmq/__init__.py +0 -28
  618. egse/zmq/spw.py +0 -160
  619. egse/zmq_ser.py +0 -41
  620. scripts/alerts/cold.yaml +0 -278
  621. scripts/alerts/example_alerts.yaml +0 -54
  622. scripts/alerts/transition.yaml +0 -14
  623. scripts/alerts/warm.yaml +0 -49
  624. scripts/analyse_n_fee_hk_data.py +0 -52
  625. scripts/check_hdf5_files.py +0 -192
  626. scripts/check_register_sync.py +0 -47
  627. scripts/check_tcs_calib_coef.py +0 -90
  628. scripts/correct_ccd_cold_temperature_cal.py +0 -157
  629. scripts/create_hdf5_report.py +0 -293
  630. scripts/csl_model.py +0 -420
  631. scripts/csl_restore_setup.py +0 -229
  632. scripts/export-grafana-dashboards.py +0 -49
  633. scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
  634. scripts/fdir/fdir_table.yaml +0 -70
  635. scripts/fdir/fdir_test_recovery.py +0 -10
  636. scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
  637. scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
  638. scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
  639. scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
  640. scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
  641. scripts/fix_csv.py +0 -80
  642. scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
  643. scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
  644. scripts/ias/correct_trp_swap_achel.py +0 -199
  645. scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
  646. scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
  647. scripts/n_fee_supply_voltage_calculation.py +0 -92
  648. scripts/playground.py +0 -30
  649. scripts/print_hdf5_hk_data.py +0 -68
  650. scripts/print_register_map.py +0 -43
  651. scripts/remove_lines_between_matches.py +0 -188
  652. scripts/sron/commanding/control_heaters.py +0 -44
  653. scripts/sron/commanding/pumpdown.py +0 -46
  654. scripts/sron/commanding/set_pid_setpoint.py +0 -19
  655. scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
  656. scripts/sron/commanding/shutdown_pumps.py +0 -33
  657. scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
  658. scripts/sron/correct_trp_swap_brigand.py +0 -204
  659. scripts/sron/gimbal_conversions.py +0 -75
  660. scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
  661. scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
  662. scripts/sron/tm_gen/tm_gen_spid.py +0 -13
  663. scripts/update_operational_cgse.py +0 -268
  664. scripts/update_operational_cgse_old.py +0 -273
@@ -1,1167 +0,0 @@
1
- """
2
- This module defines the device classes to be used to connect to and control the Hexapod PUNA from
3
- Symétrie.
4
-
5
- """
6
- import logging
7
- import math
8
- import time
9
- from datetime import datetime
10
- from datetime import timedelta
11
-
12
- import numpy as np
13
-
14
- from egse.bits import set_bit
15
- from egse.coordinates.referenceFrame import ReferenceFrame
16
- from egse.device import DeviceConnectionState
17
- from egse.device import DeviceInterface
18
- from egse.hexapod import HexapodError
19
- from egse.hexapod.symetrie import pmac
20
- from egse.hexapod.symetrie.alpha import AlphaControllerInterface
21
- from egse.hexapod.symetrie.pmac import PMACError
22
- from egse.hexapod.symetrie.pmac import PmacEthernetInterface
23
- from egse.hexapod.symetrie.pmac import decode_Q29
24
- from egse.hexapod.symetrie.pmac import decode_Q36
25
- from egse.proxy import Proxy
26
- from egse.settings import Settings
27
- from egse.zmq_ser import connect_address
28
-
29
- logger = logging.getLogger(__name__)
30
-
31
- PUNA_SETTINGS = Settings.load("PMAC Controller")
32
- CTRL_SETTINGS = Settings.load("Hexapod PUNA Control Server")
33
- DEVICE_SETTINGS = Settings.load(filename="puna.yaml")
34
-
35
- NUM_OF_DECIMALS = 6 # used for rounding numbers before sending to PMAC
36
-
37
-
38
- class PunaInterface(AlphaControllerInterface, DeviceInterface):
39
- """
40
- Interface definition for the PunaController, the PunaProxy and the PunaSimulator.
41
- """
42
-
43
-
44
- class PunaController(PunaInterface):
45
- """
46
- The PunaController class allows controlling a Symétrie PUNA Hexapod through an Ethernet
47
- interface that is connecting a Symétrie Controller.
48
-
49
- The Symétrie Controller can be either in simulation mode or have a real Hexapod
50
- connected.
51
-
52
- **Synopsis**
53
-
54
- from egse.hexapod.symetrie.puna import PunaController
55
- hexapod = PunaController(hostname="10.33.178.145", port=1025)
56
- try:
57
- hexapod.connect()
58
-
59
- # do some useful things here with the hexapod
60
-
61
- except HexapodError as exc:
62
- print(exc)
63
- finally:
64
- hexapod.disconnect()
65
-
66
- The constructor also sets the connection parameters and tries to connect
67
- to the controller. Make sure that you explicitly use the hexapod.disconnect()
68
- command when no connection is needed anymore.
69
-
70
- The controller can also be used as a context manager, in which case the `connect()`
71
- and `disconnect()` methods should not be called:
72
-
73
- with PunaController() as puna:
74
- puna.info()
75
-
76
- """
77
-
78
- SPEC_POS_MAINTENANCE = 0
79
- """Hexapod specific position, for maintenance or Jog only."""
80
- SPEC_POS_ZERO = 1
81
- """Hexapod zero position."""
82
- SPEC_POS_RETRACTED = 2
83
- """Hexapod retracted position."""
84
-
85
- def __init__(self, hostname=None, port=None):
86
- """
87
- Opens a TCP/IP socket connection with the Hexapod PUNA Hardware Controller.
88
-
89
- Args:
90
- hostname (str): the IP address or fully qualified hostname of the Hexapod hardware
91
- controller.
92
- The default is defined in the ``settings.yaml`` configuration file.
93
-
94
- port (int): the IP port number to connect to, by default set in the ``settings.yaml``
95
- configuration file.
96
-
97
- Raises:
98
- HexapodError: when the connection could not be established for some reason.
99
- """
100
-
101
- super().__init__()
102
-
103
- if hostname is None or port is None:
104
- raise ValueError(f"Please provide both hostname and port for the PunaController, {hostname=}, {port=}")
105
-
106
- logger.debug(f"Initializing PunaController with hostname={hostname} on port={port}")
107
-
108
- try:
109
- self.pmac = PmacEthernetInterface()
110
- self.pmac.setConnectionParameters(hostname, port)
111
- except PMACError as exc:
112
- logger.warning(
113
- f"HexapodError: Couldn't establish connection with the Hexapod PUNA Hardware "
114
- f"Controller: ({exc})"
115
- )
116
-
117
- def is_simulator(self):
118
- return False
119
-
120
- def is_connected(self):
121
- return self.pmac.isConnected()
122
-
123
- def connect(self):
124
- try:
125
- self.pmac.connect()
126
- except PMACError as exc:
127
- logger.warning(f"PMACError caught: Couldn't establish connection ({exc})")
128
- raise ConnectionError("Couldn't establish a connection with the Hexapod.") from exc
129
-
130
- self.notify_observers(DeviceConnectionState.DEVICE_CONNECTED)
131
-
132
- def disconnect(self):
133
- try:
134
- self.pmac.disconnect()
135
- except PMACError as exc:
136
- raise ConnectionError("Couldn't disconnect from Hexapod.") from exc
137
-
138
- self.notify_observers(DeviceConnectionState.DEVICE_NOT_CONNECTED)
139
-
140
- def reconnect(self):
141
- if self.is_connected():
142
- self.disconnect()
143
- self.connect()
144
-
145
- def is_in_position(self):
146
- try:
147
- out = self.pmac.getQVars(36, [0], int)
148
- except PMACError as exc:
149
- raise HexapodError(
150
- "Couldn't retrieve information from Hexapod PUNA Hardware Controller.") from exc
151
- return bool(out[0] & 0x04)
152
-
153
- def info(self):
154
- try:
155
- msg = "Info about the Hexapod PUNA:\n"
156
- msg += f"model = {self.pmac.getPmacModel()}\n"
157
- msg += f"CID = {self.pmac.getCID()}\n"
158
- msg += f"version = {self.pmac.getVersion()}\n"
159
- msg += f"cpu = {self.pmac.getCPU()}\n"
160
- msg += f"type = {self.pmac.getType()}\n"
161
- msg += f"vendorID= {self.pmac.getVID()}\n"
162
- msg += f"date = {self.pmac.getDate()}\n"
163
- msg += f"time = {self.pmac.getTime()}\n"
164
- msg += f"today = {self.pmac.getToday()}\n"
165
- except PMACError as exc:
166
- raise HexapodError(
167
- "Couldn't retrieve information from Hexapod PUNA Hardware Controller."
168
- ) from exc
169
-
170
- return msg
171
-
172
- def stop(self):
173
- try:
174
- rc = self.pmac.sendCommand(pmac.CMD_STOP)
175
- except PMACError as exc:
176
- raise HexapodError("Couldn't complete the STOP command.") from exc
177
-
178
- return rc
179
-
180
- def homing(self):
181
- try:
182
- rc = self.pmac.sendCommand(pmac.CMD_HOMING)
183
- except PMACError as exc:
184
- raise HexapodError("Couldn't complete the HOMING command.") from exc
185
-
186
- logger.info("Homing: Command was successful")
187
-
188
- return rc
189
-
190
- def is_homing_done(self):
191
- try:
192
- rc = self.pmac.getQVars(26, [0], int)[0]
193
- except PMACError as pmac_exc:
194
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
195
- return False
196
-
197
- msg = { # noqa: F841
198
- 0: "Homing status is undefined.",
199
- 1: "Homing is in progress",
200
- 2: "Homing is done",
201
- 3: "An error occurred during the Homing process.",
202
- }
203
-
204
- if rc == 2:
205
- return True
206
-
207
- return False
208
-
209
- def set_virtual_homing(self, tx, ty, tz, rx, ry, rz):
210
- try:
211
- rc = self.pmac.sendCommand(
212
- pmac.CMD_VIRTUAL_HOMING, tx=tx, ty=ty, tz=tz, rx=rx, ry=ry, rz=rz
213
- )
214
- except PMACError as exc:
215
- raise HexapodError("Couldn't execute the virtual homing command.") from exc
216
-
217
- logger.warning(
218
- f"Virtual Homing successfully set to {tx:.6f}, {ty:.6f}, {tz:.6f}, {rx:.6f}, "
219
- f"{ry:.6f}, {rz:.6f}."
220
- )
221
-
222
- return rc
223
-
224
- def activate_control_loop(self):
225
- try:
226
- rc = self.pmac.sendCommand(pmac.CMD_CONTROLON)
227
- except PMACError as exc:
228
- raise HexapodError("Couldn't activate the control loop.") from exc
229
-
230
- msg = { # noqa: F841
231
- 0: "Command was successful",
232
- -1: "Command was ignored",
233
- -2: "Control of the servo motors has failed",
234
- }
235
-
236
- return rc
237
-
238
- def deactivate_control_loop(self):
239
- try:
240
- rc = self.pmac.sendCommand(pmac.CMD_CONTROLOFF)
241
- except PMACError as exc:
242
- raise HexapodError("Couldn't de-activate the control loop.") from exc
243
-
244
- return rc
245
-
246
- def __move(self, cm, tx, ty, tz, rx, ry, rz):
247
- """
248
- Ask the controller to perform the movement defined by the arguments.
249
-
250
- For all control modes cm, the rotation centre coincides with the Object
251
- Coordinates System origin and the movements are controlled with translation
252
- components at first (Tx, Ty, tZ) and then the rotation components (Rx, Ry, Rz).
253
-
254
- Control mode cm:
255
- * 0 = absolute control, object coordinate system position and orientation
256
- expressed in the invariant user coordinate system
257
- * 1 = object relative, motion expressed in the Object Coordinate System
258
- * 2 = user relative, motion expressed in the User Coordinate System
259
-
260
- Args:
261
- cm (int): control mode
262
- tx (float): position on the X-axis [mm]
263
- ty (float): position on the Y-axis [mm]
264
- tz (float): position on the Z-axis [mm]
265
- rx (float): rotation around the X-axis [deg]
266
- ry (float): rotation around the Y-axis [deg]
267
- rz (float): rotation around the Z-axis [deg]
268
-
269
- Returns:
270
- 0 on success, -1 when ignored, -2 on error.
271
-
272
- Raises:
273
- PMACError: when the arguments do not match up or when there is a time out or when
274
- there is a socket
275
- communication error.
276
-
277
- .. note:: When the command was not successful, this method will query the ``POSVALID?``
278
- using the checkAbsolutePosition() and print a summary of the error messages
279
- to the log file.
280
- """
281
-
282
- rc = self.pmac.sendCommand(pmac.CMD_MOVE, cm=cm, tx=tx, ty=ty, tz=tz, rx=rx, ry=ry, rz=rz)
283
-
284
- error_code_msg = {
285
- 0: "Command was successful",
286
- -1: "Command was ignored",
287
- -2: "Command was invalid, check with POSVALID?",
288
- }
289
-
290
- if rc < 0:
291
- msg = f"Move command returned ({rc}: {error_code_msg[rc]})."
292
-
293
- if rc == -2:
294
- Q29, errors = self.__check_movement(cm, tx, ty, tz, rx, ry, rz)
295
-
296
- msg += "\nError messages returned from POSVALID?:\n"
297
- for key, value in errors.items():
298
- msg += f" bit {key:<2d}: {value}\n"
299
-
300
- logger.debug(msg)
301
-
302
- return rc
303
-
304
- def __check_movement(self, cm, tx, ty, tz, rx, ry, rz):
305
- """
306
- Ask the controller if the movement defined by the arguments is feasible.
307
-
308
- Returns a tuple where the first element is an integer that represents the
309
- bitfield encoding the errors. The second element is a dictionary with the
310
- bit numbers that were (on) and the corresponding error description.
311
-
312
- Args:
313
- tx (float): position on the X-axis [mm]
314
- ty (float): position on the Y-axis [mm]
315
- tz (float): position on the Z-axis [mm]
316
- rx (float): rotation around the X-axis [deg]
317
- ry (float): rotation around the Y-axis [deg]
318
- rz (float): rotation around the Z-axis [deg]
319
-
320
- """
321
- out = self.pmac.sendCommand(
322
- pmac.CMD_POSVALID_GET, cm=cm, tx=tx, ty=ty, tz=tz, rx=rx, ry=ry, rz=rz
323
- )
324
- Q29 = decode_Q29(out[0])
325
- return out[0], Q29
326
-
327
- def move_absolute(self, tx, ty, tz, rx, ry, rz):
328
- try:
329
- rc = self.__move(0, tx, ty, tz, rx, ry, rz)
330
- except PMACError as exc:
331
- raise HexapodError("Couldn't execute the moveAbsolute command.") from exc
332
-
333
- return rc
334
-
335
- def check_absolute_movement(self, tx, ty, tz, rx, ry, rz):
336
- return self.__check_movement(0, tx, ty, tz, rx, ry, rz)
337
-
338
- def move_relative_object(self, tx, ty, tz, rx, ry, rz):
339
- try:
340
- rc = self.__move(1, tx, ty, tz, rx, ry, rz)
341
- except PMACError as exc:
342
- raise HexapodError("Couldn't execute the relative movement [object] command.") from exc
343
-
344
- return rc
345
-
346
- def check_relative_object_movement(self, tx, ty, tz, rx, ry, rz):
347
- return self.__check_movement(1, tx, ty, tz, rx, ry, rz)
348
-
349
- def move_relative_user(self, tx, ty, tz, rx, ry, rz):
350
- try:
351
- rc = self.__move(2, tx, ty, tz, rx, ry, rz)
352
- except PMACError as exc:
353
- raise HexapodError("Couldn't execute the relative movement [user] command.") from exc
354
-
355
- return rc
356
-
357
- def check_relative_user_movement(self, tx, ty, tz, rx, ry, rz):
358
- return self.__check_movement(2, tx, ty, tz, rx, ry, rz)
359
-
360
- def perform_maintenance(self, axis):
361
- try:
362
- rc = self.pmac.sendCommand(pmac.CMD_MAINTENANCE, axis=axis)
363
- except PMACError as exc:
364
- raise HexapodError("Couldn't perform maintenance cycle.") from exc
365
-
366
- msg = {0: "Command was successfully executed", -1: "Command was ignored"} # noqa: F841
367
-
368
- return rc
369
-
370
- def goto_specific_position(self, pos):
371
- try:
372
- rc = self.pmac.sendCommand(pmac.CMD_SPECIFICPOS, pos=pos)
373
- except PMACError as exc:
374
- raise HexapodError(f"Couldn't goto specific position [pos={pos}].") from exc
375
-
376
- msg = {
377
- 0: "Command was successfully executed",
378
- -1: "Command was ignored",
379
- -2: "Invalid movement command",
380
- }
381
-
382
- logger.info(f"Goto Specific Position [{pos}]: {msg[rc]}")
383
-
384
- if rc < 0:
385
- try:
386
- out = self.pmac.getQVars(0, [29], int)
387
- except PMACError as exc:
388
- raise HexapodError("Couldn't get a response from the Hexapod controller.") from exc
389
- Q29 = decode_Q29(out[0])
390
-
391
- msg = "Error messages returned in Q29:\n"
392
- for key, value in Q29.items():
393
- msg += f" {key:2d}: {value}\n"
394
-
395
- logger.debug(msg)
396
-
397
- return rc
398
-
399
- def goto_retracted_position(self):
400
- try:
401
- rc = self.pmac.sendCommand(pmac.CMD_SPECIFICPOS, pos=self.SPEC_POS_RETRACTED)
402
- except PMACError as exc:
403
- raise HexapodError("Couldn't goto retracted position.") from exc
404
-
405
- msg = {
406
- 0: "Command was successfully executed",
407
- -1: "Command was ignored",
408
- -2: "Invalid movement command",
409
- }
410
-
411
- logger.info(f"Goto Retracted Position [2]: {msg[rc]}")
412
-
413
- if rc < 0:
414
- try:
415
- out = self.pmac.getQVars(0, [29], int)
416
- except PMACError as exc:
417
- raise HexapodError("Couldn't get a response from the Hexapod controller.") from exc
418
- Q29 = decode_Q29(out[0])
419
-
420
- msg = "Error messages returned in Q29:\n"
421
- for key, value in Q29.items():
422
- msg += f" {key:2d}: {value}\n"
423
-
424
- logger.debug(msg)
425
-
426
- return rc
427
-
428
- def goto_zero_position(self):
429
- try:
430
- rc = self.pmac.sendCommand(pmac.CMD_SPECIFICPOS, pos=self.SPEC_POS_ZERO)
431
- except PMACError as exc:
432
- raise HexapodError("Couldn't goto zero position.") from exc
433
-
434
- msg = {
435
- 0: "Command was successfully executed",
436
- -1: "Command was ignored",
437
- -2: "Invalid movement command",
438
- }
439
-
440
- logger.info(f"Goto Zero Position [1]: {msg[rc]}")
441
-
442
- if rc < 0:
443
- try:
444
- out = self.pmac.getQVars(0, [29], int)
445
- except PMACError as exc:
446
- raise HexapodError("Couldn't get a response from the Hexapod controller.") from exc
447
- Q29 = decode_Q29(out[0])
448
-
449
- msg = "Error messages returned in Q29:\n"
450
- for key, value in Q29.items():
451
- msg += f" {key:2d}: {value}\n"
452
-
453
- logger.debug(msg)
454
-
455
- return rc
456
-
457
- def get_buffer(self):
458
- return_string = self.pmac.getBuffer()
459
- return return_string
460
-
461
- def clear_error(self):
462
- try:
463
- rc = self.pmac.sendCommand(pmac.CMD_CLEARERROR)
464
- except PMACError as exc:
465
- raise HexapodError("Couldn't clear errors in the controller software.") from exc
466
-
467
- return rc
468
-
469
- def jog(self, axis: int, inc: float) -> int:
470
- if not (1 <= axis <= 6):
471
- logger.error(f"The axis argument must be 1 <= axis <= 6, given {axis}.")
472
- raise HexapodError("Illegal Argument Value: axis is {axis}, should be 1 <= axis <= 6.")
473
-
474
- try:
475
- rc = self.pmac.sendCommand(pmac.CMD_JOG, axis=axis, inc=inc)
476
- except PMACError as exc:
477
- raise HexapodError(
478
- f"Couldn't execute the jog command for axis={axis} with inc={inc} [mm]."
479
- ) from exc
480
-
481
- msg = {0: "Command was successfully executed", -1: "Command was ignored"}
482
-
483
- logger.info(f"JOG on axis [{axis}] of {inc} mm: {msg[rc]}")
484
-
485
- return rc
486
-
487
- def configure_coordinates_systems(
488
- self, tx_u, ty_u, tz_u, rx_u, ry_u, rz_u, tx_o, ty_o, tz_o, rx_o, ry_o, rz_o
489
- ):
490
- try:
491
-
492
- rc = self.pmac.sendCommand(
493
- pmac.CMD_CFG_CS,
494
- tx_u=round(tx_u, NUM_OF_DECIMALS),
495
- ty_u=round(ty_u, NUM_OF_DECIMALS),
496
- tz_u=round(tz_u, NUM_OF_DECIMALS),
497
- rx_u=round(rx_u, NUM_OF_DECIMALS),
498
- ry_u=round(ry_u, NUM_OF_DECIMALS),
499
- rz_u=round(rz_u, NUM_OF_DECIMALS),
500
- tx_o=round(tx_o, NUM_OF_DECIMALS),
501
- ty_o=round(ty_o, NUM_OF_DECIMALS),
502
- tz_o=round(tz_o, NUM_OF_DECIMALS),
503
- rx_o=round(rx_o, NUM_OF_DECIMALS),
504
- ry_o=round(ry_o, NUM_OF_DECIMALS),
505
- rz_o=round(rz_o, NUM_OF_DECIMALS),
506
- )
507
- except PMACError as exc:
508
- raise HexapodError(
509
- "Couldn't configure coordinate systems on the hexapod controller."
510
- ) from exc
511
-
512
- return rc
513
-
514
- def get_coordinates_systems(self):
515
- try:
516
- out = self.pmac.sendCommand(pmac.CMD_CFG_CS_GET)
517
- except PMACError as exc:
518
- raise HexapodError(
519
- "Couldn't get the coordinate systems information from the hexapod controller."
520
- ) from exc
521
-
522
- return out
523
-
524
- def get_debug_info(self):
525
- try:
526
- out = self.pmac.sendCommand(pmac.CMD_STATE_DEBUG_GET)
527
- except PMACError as exc:
528
- raise HexapodError(
529
- "Couldn't get the debugging information from the hexapod controller."
530
- ) from exc
531
-
532
- return out
533
-
534
- def set_speed(self, vt, vr):
535
- try:
536
- rc = self.pmac.sendCommand(pmac.CMD_CFG_SPEED, vt=vt, vr=vr)
537
- except PMACError as exc:
538
- raise HexapodError(
539
- "Couldn't set the speed for translation [{vt} mm/s] or rotation [{vr} deg/s]."
540
- ) from exc
541
-
542
- return rc
543
-
544
- def get_speed(self):
545
- try:
546
- out = self.pmac.sendCommand(pmac.CMD_CFG_SPEED_GET)
547
- except PMACError as exc:
548
- raise HexapodError(
549
- "Couldn't get the speed settings from the hexapod controller."
550
- ) from exc
551
-
552
- return out
553
-
554
- def get_general_state(self):
555
- try:
556
- out = self.pmac.getQVars(36, [0], int)
557
- except PMACError as pmac_exc:
558
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
559
- return None
560
-
561
- return out[0], pmac.decode_Q36(out[0])
562
-
563
- def get_actuator_state(self):
564
- try:
565
- out = self.pmac.getQVars(30, [0, 1, 2, 3, 4, 5], int)
566
- except PMACError as pmac_exc:
567
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
568
- return None
569
-
570
- return [pmac.decode_Q30(value) for value in out]
571
-
572
- def get_user_positions(self):
573
- try:
574
- # out = self.pmac.getQVars(53, [0, 1, 2, 3, 4, 5], float)
575
- out = self.pmac.sendCommand(pmac.CMD_POSUSER_GET)
576
- except PMACError as pmac_exc:
577
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
578
- return None
579
-
580
- return out
581
-
582
- def get_machine_positions(self):
583
- try:
584
- out = self.pmac.getQVars(47, [0, 1, 2, 3, 4, 5], float)
585
- except PMACError as pmac_exc:
586
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
587
- return None
588
-
589
- return out
590
-
591
- def get_actuator_length(self):
592
- try:
593
- out = self.pmac.getQVars(41, [0, 1, 2, 3, 4, 5], float)
594
- except PMACError as pmac_exc:
595
- logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
596
- return None
597
-
598
- return out
599
-
600
- def reset(self, wait=True, verbose=False):
601
- try:
602
- self.pmac.sendCommand(pmac.CMD_RESETSOFT)
603
- except PMACError as exc:
604
- raise HexapodError("Couldn't (soft) reset the hexapod controller.") from exc
605
-
606
- # How do I know when the RESETSOFT has finished and we can send further commands?
607
-
608
- if wait:
609
- logger.info("Sent a soft reset, this will take about 30 seconds to complete.")
610
- self.__wait(30, verbose=verbose)
611
-
612
- def __wait(self, duration, verbose=False):
613
- """
614
- Wait for a specific duration in seconds.
615
- """
616
- _timeout = timedelta(seconds=duration)
617
- _start = datetime.now()
618
-
619
- _rate = timedelta(seconds=5) # every _rate seconds print a message
620
- _count = 0
621
-
622
- logger.info(f"Just waiting {duration} seconds ...")
623
-
624
- while datetime.now() - _start < _timeout:
625
-
626
- if verbose and (datetime.now() - _start > _count * _rate):
627
- _count += 1
628
- logger.info(f"waited for {_count * _rate} of {_timeout} seconds, ")
629
- print(f"waited for {_count * _rate} of {_timeout} seconds, ")
630
-
631
- time.sleep(0.01)
632
-
633
-
634
- class PunaSimulator(PunaInterface):
635
- """
636
- HexapodSimulator simulates the Symétrie Hexapod PUNA. The class is heavily based on the
637
- ReferenceFrames in the `egse.coordinates` package.
638
-
639
- The simulator implements the same methods as the HexapodController class which acts on the
640
- real hardware controller in either simulation mode or with a real Hexapod PUNA connected.
641
-
642
- Therefore, the HexapodSimulator can be used instead of the Hexapod class in test harnesses
643
- and when the hardware is not available.
644
-
645
- This class simulates all the movements and status of the Hexapod.
646
- """
647
-
648
- def __init__(self):
649
-
650
- identity = np.identity(4)
651
-
652
- # Rotation around static axis, and around x, y and z in that order
653
- self.rot_config = "sxyz"
654
-
655
- # Configure the Master Reference Frame
656
- self.cs_master = ReferenceFrame.createMaster()
657
-
658
- # Configure the Machine Coordinate System, i.e. cs_mec [ref:cs_master]
659
- self.cs_machine = ReferenceFrame(
660
- transformation=identity,
661
- ref=self.cs_master,
662
- name="Machine[Master]",
663
- rot_config=self.rot_config,
664
- )
665
-
666
- # Configure the Platform Coordinate System, i.e. cs_platform [ref:cs_machine]
667
- # default after homing: PLATFORM = MACHINE
668
-
669
- self.cs_platform = ReferenceFrame(
670
- transformation=identity,
671
- ref=self.cs_machine,
672
- name="Platform[Machine]",
673
- rot_config=self.rot_config,
674
- )
675
-
676
- # Configure the User Coordinate System, i.e. cs_user [ref:cs_machine]
677
- self.cs_user = ReferenceFrame(
678
- transformation=identity,
679
- ref=self.cs_machine,
680
- name="User[Machine]",
681
- rot_config=self.rot_config,
682
- )
683
-
684
- # Configure the Object Coordinate System, i.e. cs_object [ref:cs_platform]
685
- self.cs_object = ReferenceFrame(
686
- transformation=identity,
687
- ref=self.cs_platform,
688
- name="Object[Platform]",
689
- rot_config=self.rot_config,
690
- )
691
-
692
- # We use a CS called cs_object_in_user, i.e. Object as defined in the User CS,
693
- # and we define this
694
- # from the transformation user -> object.
695
-
696
- tf_user_to_object = self.cs_user.getActiveTransformationTo(self.cs_object)
697
- self.cs_object_in_user = ReferenceFrame(
698
- tf_user_to_object, rot_config=self.rot_config, ref=self.cs_user, name="Object[User]"
699
- )
700
-
701
- # Define the invariant links within the system, i.e. some systems are bound with an
702
- # invariant transformation
703
- # matrix and those links shall be preserved throughout the movement within the system.
704
-
705
- # We link this cs_object_in_user to cs_object with the identity transformation,
706
- # which connects them together
707
-
708
- self.cs_object_in_user.addLink(self.cs_object, transformation=identity)
709
-
710
- # The User Coordinate System is linked to the Machine Coordinate System
711
-
712
- self.cs_machine.addLink(self.cs_user, transformation=self.cs_user.transformation)
713
-
714
- # The Object Coordinate System is linked to the Platform Coordinate System
715
-
716
- self.cs_platform.addLink(self.cs_object, transformation=self.cs_object.transformation)
717
-
718
- # Keep a record if the homing() command has been executed.
719
-
720
- self.homing_done = False
721
- self.control_loop = False
722
- self._virtual_homing = False
723
- self._virtual_homing_position = None
724
-
725
- # Just keep the speed settings, no used in movement currently
726
-
727
- self._speed = [1.0, 1.0, 0.01, 0.001, 4.0, 2.0]
728
-
729
- # Print out some debugging information
730
-
731
- logger.debug(
732
- f"Linked to cs_object_in_user {[i.name for i in self.cs_object_in_user.linkedTo]}"
733
- )
734
- logger.debug(f"Linked to cs_object {[i.name for i in self.cs_object.linkedTo]}")
735
- logger.debug(f"Linked to cs_platform {[i.name for i in self.cs_platform.linkedTo]}")
736
- logger.debug(
737
- f"Linked to cs_machine {[i.name for i in self.cs_machine.linkedTo or {}]}"
738
- )
739
-
740
- def is_simulator(self):
741
- return True
742
-
743
- def connect(self):
744
- pass
745
-
746
- def reconnect(self):
747
- pass
748
-
749
- def disconnect(self):
750
- # TODO:
751
- # Should I keep state in this class to check if it has been disconnected?
752
- #
753
- # TODO:
754
- # What happens when I re-connect to this Simulator? Shall it be in Homing position or
755
- # do I have to keep state via a persistency mechanism?
756
- pass
757
-
758
- def is_connected(self):
759
- return True
760
-
761
- def reset(self, wait=True, verbose=False):
762
- # TODO:
763
- # Find out what exactly a reset() should be doing. Does it bring back the Hexapod
764
- # in it's original state, loosing all definitions of coordinate systems? Or does it
765
- # do a clearError() and a homing()?
766
- pass
767
-
768
- def homing(self):
769
- self.goto_zero_position()
770
- self.homing_done = True
771
- self._virtual_homing = False
772
- self._virtual_homing_position = None
773
- return 0
774
-
775
- def is_homing_done(self):
776
- return self.homing_done
777
-
778
- def set_virtual_homing(self, tx, ty, tz, rx, ry, rz):
779
- self._virtual_homing_position = [tx, ty, tz, rx, ry, rz]
780
- self._virtual_homing = True
781
- return 0
782
-
783
- def stop(self):
784
- pass
785
-
786
- def clear_error(self):
787
- return 0
788
-
789
- def activate_control_loop(self):
790
- self.control_loop = True
791
- return self.control_loop
792
-
793
- def deactivate_control_loop(self):
794
- self.control_loop = False
795
- return self.control_loop
796
-
797
- def configure_coordinates_systems(
798
- self, tx_u, ty_u, tz_u, rx_u, ry_u, rz_u, tx_o, ty_o, tz_o, rx_o, ry_o, rz_o
799
- ):
800
- identity = np.identity(4)
801
-
802
- # Redefine the User Coordinate System
803
-
804
- translation = np.array([tx_u, ty_u, tz_u])
805
- rotation = np.array([rx_u, ry_u, rz_u])
806
- degrees = True
807
-
808
- # Remove the old links between user and machine CS, and between Object in User and Object CS
809
-
810
- self.cs_machine.removeLink(self.cs_user)
811
- self.cs_object_in_user.removeLink(self.cs_object)
812
-
813
- # Redefine the User Coordinate System
814
-
815
- self.cs_user = ReferenceFrame.fromTranslationRotation(
816
- translation,
817
- rotation,
818
- rot_config=self.rot_config,
819
- ref=self.cs_machine,
820
- name="User[Machine]",
821
- degrees=degrees,
822
- )
823
-
824
- # Redefine the Object in User Coordinate System
825
-
826
- tf_user_to_object = self.cs_user.getActiveTransformationTo(self.cs_object)
827
- self.cs_object_in_user = ReferenceFrame(
828
- tf_user_to_object, rot_config=self.rot_config, ref=self.cs_user, name="Object[User]"
829
- )
830
-
831
- # Define the invariant links within the system, i.e. some systems are bound with an
832
- # invariant transformation
833
- # matrix and those links shall be preserved throughout the movement within the system.
834
-
835
- # User and Machine CS are invariant, reset the transformation. User in Object is
836
- # identical to Object
837
-
838
- self.cs_machine.addLink(self.cs_user, transformation=self.cs_user.transformation)
839
- self.cs_object_in_user.addLink(self.cs_object, transformation=identity)
840
-
841
- # Redefine the Object Coordinates System
842
-
843
- translation = np.array([tx_o, ty_o, tz_o])
844
- rotation = np.array([rx_o, ry_o, rz_o])
845
- degrees = True
846
-
847
- # Remove the old links between user and machine CS, and between Object in User and Object CS
848
-
849
- self.cs_platform.removeLink(self.cs_object)
850
- self.cs_object_in_user.removeLink(self.cs_object)
851
-
852
- self.cs_object = ReferenceFrame.fromTranslationRotation(
853
- translation,
854
- rotation,
855
- rot_config=self.rot_config,
856
- ref=self.cs_platform,
857
- name="Object[Platform]",
858
- degrees=degrees,
859
- )
860
-
861
- # Redefine the Object in User Coordinate System
862
-
863
- tf_user_to_object = self.cs_user.getActiveTransformationTo(self.cs_object)
864
- self.cs_object_in_user = ReferenceFrame(
865
- tf_user_to_object, rot_config=self.rot_config, ref=self.cs_user, name="Object[User]"
866
- )
867
-
868
- # Object CS and Platform CS are invariant, reset the transformation. User in Object is
869
- # identical to Object
870
-
871
- self.cs_platform.addLink(self.cs_object, transformation=self.cs_object.transformation)
872
- self.cs_object_in_user.addLink(self.cs_object, transformation=identity)
873
-
874
- return 0
875
-
876
- def get_coordinates_systems(self):
877
-
878
- degrees = True
879
-
880
- t_user, r_user = self.cs_user.getTranslationRotationVectors(degrees=degrees)
881
- t_object, r_object = self.cs_object.getTranslationRotationVectors(degrees=degrees)
882
-
883
- return list(np.concatenate((t_user, r_user, t_object, r_object)))
884
-
885
- def move_absolute(self, tx, ty, tz, rx, ry, rz):
886
- # FIXME:
887
- # to really simulate the behavior of the Hexapod, this method should implement limit
888
- # checking
889
- # and other condition or error checking, e.g. argument matching, etc.
890
-
891
- logger.debug(f"moveAbsolute with {tx}, {ty}, {tz}, {rx}, {ry}, {rz}")
892
-
893
- translation = np.array([tx, ty, tz])
894
- rotation = np.array([rx, ry, rz])
895
-
896
- # We set a new transformation for cs_object_in_user which will update our model,
897
- # because cs_object and cs_object_in_user are linked.
898
-
899
- self.cs_object_in_user.setTranslationRotation(
900
- translation,
901
- rotation,
902
- rot_config=self.rot_config,
903
- active=True,
904
- degrees=True,
905
- preserveLinks=True,
906
- )
907
-
908
- return 0
909
-
910
- def move_relative_object(self, tx, ty, tz, rx, ry, rz):
911
-
912
- tr_rel = np.array([tx, ty, tz])
913
- rot_rel = np.array([rx, ry, rz])
914
-
915
- self.cs_object.applyTranslationRotation(
916
- tr_rel,
917
- rot_rel,
918
- rot_config=self.rot_config,
919
- active=True,
920
- degrees=True,
921
- preserveLinks=True,
922
- )
923
-
924
- def move_relative_user(self, tx, ty, tz, rx, ry, rz):
925
-
926
- # The Symétrie Hexapod definition of moveRelativeUser
927
- #
928
- # - Translation and rotations are expressed in USER reference frame
929
- #
930
- # - Actually,
931
- # - the translations happen parallel to the USER reference frame
932
- # - the rotations are applied after the translations, on the OBJ ReferenceFrame
933
- #
934
- # To achieve this,
935
- #
936
- # * OBUSR is "de-rotated", to become parallel to USR
937
- # * the requested translation is applied
938
- # * OBUSR is "re-rotated" to its original orientation
939
- # * the requested rotation is applied
940
-
941
- # Derotation of cs_object --> cs_user
942
-
943
- derotation = self.cs_object.getActiveTransformationTo(self.cs_user)
944
- derotation[:3, 3] = [0, 0, 0]
945
-
946
- # Reverse rotation
947
-
948
- rerotation = derotation.T
949
-
950
- # Requested translation matrix
951
-
952
- translation = np.identity(4)
953
- translation[:3, 3] = [tx, ty, tz]
954
-
955
- # Requested rotation matrix
956
-
957
- import egse.coordinates.transform3d_addon as t3add
958
-
959
- rotation = t3add.translationRotationToTransformation(
960
- [0, 0, 0], [rx, ry, rz], rot_config=self.rot_config
961
- )
962
-
963
- transformation = derotation @ translation @ rerotation @ rotation
964
-
965
- # Adapt our model
966
-
967
- self.cs_object.applyTransformation(transformation)
968
-
969
- def check_absolute_movement(self, tx, ty, tz, rx, ry, rz):
970
- rc = 0
971
- rc_dict = {}
972
- if not -30.0 <= tx <= 30.0:
973
- rc += 1
974
- rc_dict.update({1: "Tx should be in range ±30.0 mm"})
975
- if not -30.0 <= ty <= 30.0:
976
- rc += 1
977
- rc_dict.update({2: "Ty should be in range ±30.0 mm"})
978
- if not -20.0 <= tz <= 20.0:
979
- rc += 1
980
- rc_dict.update({3: "Tz should be in range ±20.0 mm"})
981
- if not -11.0 <= rx <= 11.0:
982
- rc += 1
983
- rc_dict.update({4: "Rx should be in range ±11.0 mm"})
984
- if not -11.0 <= ry <= 11.0:
985
- rc += 1
986
- rc_dict.update({5: "Ry should be in range ±11.0 mm"})
987
- if not -20.0 <= rz <= 20.0:
988
- rc += 1
989
- rc_dict.update({6: "Rz should be in range ±20.0 mm"})
990
- return rc, rc_dict
991
-
992
- def check_relative_object_movement(self, tx, ty, tz, rx, ry, rz):
993
- return 0, {}
994
-
995
- def check_relative_user_movement(self, tx, ty, tz, rx, ry, rz):
996
- return 0, {}
997
-
998
- def get_user_positions(self):
999
- t, r = self.cs_user.getActiveTranslationRotationVectorsTo(self.cs_object_in_user)
1000
-
1001
- pos = list(np.concatenate((t, r)))
1002
-
1003
- return pos
1004
-
1005
- def get_machine_positions(self):
1006
- t, r = self.cs_platform.getTranslationRotationVectors()
1007
- t, r = self.cs_machine.getActiveTranslationRotationVectorsTo(self.cs_platform)
1008
-
1009
- pos = list(np.concatenate((t, r)))
1010
-
1011
- return pos
1012
-
1013
- def get_actuator_length(self):
1014
- alen = [math.nan for _ in range(6)]
1015
-
1016
- return alen
1017
-
1018
- def get_general_state(self):
1019
- state = 0
1020
- state = set_bit(state, 1) # System Initialized
1021
- state = set_bit(state, 2) # In Position
1022
- if self.homing_done:
1023
- state = set_bit(state, 4)
1024
- if self.control_loop:
1025
- state = set_bit(state, 3)
1026
- if self._virtual_homing:
1027
- state = set_bit(state, 18)
1028
- return state, decode_Q36(state)
1029
-
1030
- def goto_specific_position(self, pos):
1031
- return 0
1032
-
1033
- def goto_retracted_position(self):
1034
- translation = np.array([0, 0, -20])
1035
- rotation = np.array([0, 0, 0])
1036
-
1037
- self.cs_platform.setTranslationRotation(
1038
- translation,
1039
- rotation,
1040
- rot_config=self.rot_config,
1041
- active=True,
1042
- degrees=True,
1043
- preserveLinks=True,
1044
- )
1045
-
1046
- return 0
1047
-
1048
- def goto_zero_position(self):
1049
- # We set a new transformation for cs_platform which will update our model.
1050
- # See issue #58: updating the cs_platform is currently not a good idea because that will
1051
- # not properly update the chain/path upwards, i.e. the chain/path is followed in the
1052
- # direction of the references that are defined, not in the other direction.
1053
- #
1054
- translation = np.array([0, 0, 0])
1055
- rotation = np.array([0, 0, 0])
1056
-
1057
- self.cs_platform.setTranslationRotation(
1058
- translation,
1059
- rotation,
1060
- rot_config=self.rot_config,
1061
- active=True,
1062
- degrees=True,
1063
- preserveLinks=True,
1064
- )
1065
-
1066
- # As a work around for the bug in issue #58, we determine the transformation from
1067
- # cs_object as it is
1068
- # invariantly linked with cs_platform. Updating cs_object_in_user with that
1069
- # transformation will
1070
- # properly update all the reference frames.
1071
-
1072
- # tr_abs, rot_abs = self.cs_object.getTranslationRotationVectors()
1073
- #
1074
- # self.cs_object_in_user.setTranslationRotation(
1075
- # tr_abs,
1076
- # rot_abs,
1077
- # rot_config=self.rot_config,
1078
- # active=True,
1079
- # degrees=True,
1080
- # preserveLinks=True,
1081
- # )
1082
-
1083
- return 0
1084
-
1085
- def is_in_position(self):
1086
- return True
1087
-
1088
- def jog(self, axis: int, inc: float) -> int:
1089
- pass
1090
-
1091
- def get_debug_info(self):
1092
- pass
1093
-
1094
- def set_speed(self, vt, vr):
1095
- self._speed[0] = vt
1096
- self._speed[1] = vr
1097
-
1098
- def get_speed(self):
1099
- return tuple(self._speed)
1100
-
1101
- def get_actuator_state(self):
1102
- return [({0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1103
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1104
- 6: 'Brake control output'},
1105
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
1106
- {0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1107
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1108
- 6: 'Brake control output'},
1109
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
1110
- {0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1111
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1112
- 6: 'Brake control output'},
1113
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
1114
- {0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1115
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1116
- 6: 'Brake control output'},
1117
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
1118
- {0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1119
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1120
- 6: 'Brake control output'},
1121
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
1122
- {0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
1123
- 4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
1124
- 6: 'Brake control output'},
1125
- [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
1126
-
1127
- def perform_maintenance(self, axis):
1128
- pass
1129
-
1130
- def info(self):
1131
-
1132
- msg = "Info about the PunaSimulator:\n"
1133
- msg += "\n"
1134
- msg += "This Hexapod PUNA Simulator works with several reference frames:\n"
1135
- msg += " * The machine reference frame\n"
1136
- msg += " * The platform reference frame\n"
1137
- msg += " * The object reference frame\n"
1138
- msg += " * The user reference frame\n\n"
1139
- msg += (
1140
- "Any movement commands result in a transformation of the appropriate coordinate "
1141
- "systems."
1142
- )
1143
-
1144
- logger.info(msg)
1145
-
1146
- return msg
1147
-
1148
-
1149
- class PunaProxy(Proxy, PunaInterface):
1150
- """The PunaProxy class is used to connect to the control server and send commands to the
1151
- Hexapod PUNA remotely."""
1152
-
1153
- def __init__(
1154
- self,
1155
- protocol=CTRL_SETTINGS.PROTOCOL,
1156
- hostname=CTRL_SETTINGS.HOSTNAME,
1157
- port=CTRL_SETTINGS.COMMANDING_PORT,
1158
- ):
1159
- """
1160
- Args:
1161
- protocol: the transport protocol [default is taken from settings file]
1162
- hostname: location of the control server (IP address) [default is taken from settings
1163
- file]
1164
- port: TCP port on which the control server is listening for commands [default is
1165
- taken from settings file]
1166
- """
1167
- super().__init__(connect_address(protocol, hostname, port))