cgse 2024.7.0__py3-none-any.whl → 2025.0.2__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.
- README.md +27 -0
- bump.py +85 -0
- cgse-2025.0.2.dist-info/METADATA +38 -0
- cgse-2025.0.2.dist-info/RECORD +5 -0
- {cgse-2024.7.0.dist-info → cgse-2025.0.2.dist-info}/WHEEL +1 -2
- cgse-2024.7.0.dist-info/COPYING +0 -674
- cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
- cgse-2024.7.0.dist-info/METADATA +0 -144
- cgse-2024.7.0.dist-info/RECORD +0 -660
- cgse-2024.7.0.dist-info/entry_points.txt +0 -75
- cgse-2024.7.0.dist-info/top_level.txt +0 -2
- egse/__init__.py +0 -12
- egse/__main__.py +0 -32
- egse/aeu/aeu.py +0 -5238
- egse/aeu/aeu_awg.yaml +0 -265
- egse/aeu/aeu_crio.yaml +0 -273
- egse/aeu/aeu_cs.py +0 -627
- egse/aeu/aeu_devif.py +0 -321
- egse/aeu/aeu_main_ui.py +0 -903
- egse/aeu/aeu_metrics.py +0 -131
- egse/aeu/aeu_protocol.py +0 -463
- egse/aeu/aeu_psu.yaml +0 -204
- egse/aeu/aeu_ui.py +0 -873
- egse/aeu/arbdata/FccdRead.arb +0 -2
- egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
- egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/ccdRead25.arb +0 -2
- egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead50.arb +0 -2
- egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
- egse/alert/__init__.py +0 -1049
- egse/alert/alertman.yaml +0 -37
- egse/alert/alertman_cs.py +0 -233
- egse/alert/alertman_ui.py +0 -600
- egse/alert/gsm/beaglebone.py +0 -138
- egse/alert/gsm/beaglebone.yaml +0 -51
- egse/alert/gsm/beaglebone_cs.py +0 -108
- egse/alert/gsm/beaglebone_devif.py +0 -122
- egse/alert/gsm/beaglebone_protocol.py +0 -46
- egse/bits.py +0 -318
- egse/camera.py +0 -44
- egse/collimator/__init__.py +0 -0
- egse/collimator/fcul/__init__.py +0 -0
- egse/collimator/fcul/ogse.py +0 -1077
- egse/collimator/fcul/ogse.yaml +0 -14
- egse/collimator/fcul/ogse_cs.py +0 -154
- egse/collimator/fcul/ogse_devif.py +0 -358
- egse/collimator/fcul/ogse_protocol.py +0 -132
- egse/collimator/fcul/ogse_sim.py +0 -431
- egse/collimator/fcul/ogse_ui.py +0 -1108
- egse/command.py +0 -699
- egse/config.py +0 -410
- egse/confman/__init__.py +0 -1058
- egse/confman/confman.yaml +0 -70
- egse/confman/confman_cs.py +0 -240
- egse/confman/confman_ui.py +0 -381
- egse/confman/setup_ui.py +0 -565
- egse/control.py +0 -632
- egse/coordinates/__init__.py +0 -534
- egse/coordinates/avoidance.py +0 -100
- egse/coordinates/cslmodel.py +0 -127
- egse/coordinates/laser_tracker_to_dict.py +0 -122
- egse/coordinates/point.py +0 -707
- egse/coordinates/pyplot.py +0 -194
- egse/coordinates/referenceFrame.py +0 -1279
- egse/coordinates/refmodel.py +0 -737
- egse/coordinates/rotationMatrix.py +0 -85
- egse/coordinates/transform3d_addon.py +0 -419
- egse/csl/__init__.py +0 -50
- egse/csl/commanding.py +0 -78
- egse/csl/icons/hexapod-connected-selected.svg +0 -30
- egse/csl/icons/hexapod-connected.svg +0 -30
- egse/csl/icons/hexapod-homing-selected.svg +0 -68
- egse/csl/icons/hexapod-homing.svg +0 -68
- egse/csl/icons/hexapod-retract-selected.svg +0 -56
- egse/csl/icons/hexapod-retract.svg +0 -51
- egse/csl/icons/hexapod-zero-selected.svg +0 -56
- egse/csl/icons/hexapod-zero.svg +0 -56
- egse/csl/icons/logo-puna.svg +0 -92
- egse/csl/icons/stop.svg +0 -1
- egse/csl/initialisation.py +0 -102
- egse/csl/mech_pos_settings.yaml +0 -18
- egse/das.py +0 -1240
- egse/das.yaml +0 -7
- egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
- egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
- egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
- egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
- egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
- egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
- egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
- egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
- egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
- egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
- egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
- egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
- egse/decorators.py +0 -514
- egse/device.py +0 -269
- egse/dpu/__init__.py +0 -2698
- egse/dpu/ccd_ui.py +0 -514
- egse/dpu/dpu.py +0 -783
- egse/dpu/dpu.yaml +0 -153
- egse/dpu/dpu_cs.py +0 -272
- egse/dpu/dpu_ui.py +0 -671
- egse/dpu/fitsgen.py +0 -2096
- egse/dpu/fitsgen_ui.py +0 -399
- egse/dpu/hdf5_model.py +0 -332
- egse/dpu/hdf5_ui.py +0 -277
- egse/dpu/hdf5_viewer.py +0 -506
- egse/dpu/hk_ui.py +0 -468
- egse/dpu_commands.py +0 -81
- egse/dsi/__init__.py +0 -33
- egse/dsi/_libesl.py +0 -232
- egse/dsi/constants.py +0 -296
- egse/dsi/esl.py +0 -630
- egse/dsi/rmap.py +0 -444
- egse/dsi/rmapci.py +0 -39
- egse/dsi/spw.py +0 -335
- egse/dsi/spw_state.py +0 -29
- egse/dummy.py +0 -318
- egse/dyndummy.py +0 -179
- egse/env.py +0 -278
- egse/exceptions.py +0 -88
- egse/fdir/__init__.py +0 -26
- egse/fdir/fdir_manager.py +0 -85
- egse/fdir/fdir_manager.yaml +0 -37
- egse/fdir/fdir_manager_controller.py +0 -136
- egse/fdir/fdir_manager_cs.py +0 -164
- egse/fdir/fdir_manager_interface.py +0 -15
- egse/fdir/fdir_remote.py +0 -73
- egse/fdir/fdir_remote.yaml +0 -30
- egse/fdir/fdir_remote_controller.py +0 -30
- egse/fdir/fdir_remote_cs.py +0 -94
- egse/fdir/fdir_remote_interface.py +0 -9
- egse/fdir/fdir_remote_popup.py +0 -26
- egse/fee/__init__.py +0 -106
- egse/fee/f_fee_register.yaml +0 -43
- egse/fee/feesim.py +0 -914
- egse/fee/n_fee_hk.py +0 -768
- egse/fee/nfee.py +0 -188
- egse/filterwheel/__init__.py +0 -4
- egse/filterwheel/eksma/__init__.py +0 -49
- egse/filterwheel/eksma/fw8smc4.py +0 -657
- egse/filterwheel/eksma/fw8smc4.yaml +0 -121
- egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
- egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
- egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
- egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
- egse/filterwheel/eksma/fw8smc5.py +0 -115
- egse/filterwheel/eksma/fw8smc5.yaml +0 -105
- egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
- egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
- egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
- egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
- egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
- egse/filterwheel/eksma/testpythonfw.py +0 -215
- egse/fov/__init__.py +0 -65
- egse/fov/fov_hk.py +0 -710
- egse/fov/fov_ui.py +0 -859
- egse/fov/fov_ui_controller.py +0 -140
- egse/fov/fov_ui_model.py +0 -200
- egse/fov/fov_ui_view.py +0 -345
- egse/gimbal/__init__.py +0 -32
- egse/gimbal/symetrie/__init__.py +0 -26
- egse/gimbal/symetrie/alpha.py +0 -586
- egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
- egse/gimbal/symetrie/gimbal.py +0 -877
- egse/gimbal/symetrie/gimbal.yaml +0 -168
- egse/gimbal/symetrie/gimbal_cs.py +0 -183
- egse/gimbal/symetrie/gimbal_protocol.py +0 -138
- egse/gimbal/symetrie/gimbal_ui.py +0 -361
- egse/gimbal/symetrie/pmac.py +0 -1006
- egse/gimbal/symetrie/pmac_regex.py +0 -83
- egse/graph.py +0 -132
- egse/gui/__init__.py +0 -47
- egse/gui/buttons.py +0 -378
- egse/gui/focalplane.py +0 -1285
- egse/gui/formatter.py +0 -10
- egse/gui/led.py +0 -162
- egse/gui/limitswitch.py +0 -143
- egse/gui/mechanisms.py +0 -587
- egse/gui/states.py +0 -148
- egse/gui/stripchart.py +0 -729
- egse/gui/styles.qss +0 -48
- egse/gui/switch.py +0 -112
- egse/h5.py +0 -274
- egse/help/__init__.py +0 -0
- egse/help/help_ui.py +0 -126
- egse/hexapod/__init__.py +0 -32
- egse/hexapod/symetrie/__init__.py +0 -137
- egse/hexapod/symetrie/alpha.py +0 -874
- egse/hexapod/symetrie/dynalpha.py +0 -1387
- egse/hexapod/symetrie/hexapod_ui.py +0 -1516
- egse/hexapod/symetrie/pmac.py +0 -1010
- egse/hexapod/symetrie/pmac_regex.py +0 -83
- egse/hexapod/symetrie/puna.py +0 -1167
- egse/hexapod/symetrie/puna.yaml +0 -193
- egse/hexapod/symetrie/puna_cs.py +0 -195
- egse/hexapod/symetrie/puna_protocol.py +0 -134
- egse/hexapod/symetrie/puna_ui.py +0 -433
- egse/hexapod/symetrie/punaplus.py +0 -107
- egse/hexapod/symetrie/zonda.py +0 -872
- egse/hexapod/symetrie/zonda.yaml +0 -337
- egse/hexapod/symetrie/zonda_cs.py +0 -172
- egse/hexapod/symetrie/zonda_devif.py +0 -414
- egse/hexapod/symetrie/zonda_protocol.py +0 -123
- egse/hexapod/symetrie/zonda_ui.py +0 -449
- egse/hk.py +0 -791
- egse/icons/aeu-cs-start.svg +0 -117
- egse/icons/aeu-cs-stop.svg +0 -118
- egse/icons/aeu-cs.svg +0 -107
- egse/icons/aeu_cs-started.svg +0 -112
- egse/icons/aeu_cs-stopped.svg +0 -112
- egse/icons/aeu_cs.svg +0 -55
- egse/icons/alert.svg +0 -1
- egse/icons/arrow-double-left.png +0 -0
- egse/icons/arrow-double-right.png +0 -0
- egse/icons/arrow-up.svg +0 -11
- egse/icons/backward.svg +0 -1
- egse/icons/busy.svg +0 -1
- egse/icons/cleaning.svg +0 -115
- egse/icons/color-scheme.svg +0 -1
- egse/icons/cs-connected-alert.svg +0 -91
- egse/icons/cs-connected-disabled.svg +0 -43
- egse/icons/cs-connected.svg +0 -89
- egse/icons/cs-not-connected.svg +0 -44
- egse/icons/double-left-arrow.svg +0 -1
- egse/icons/double-right-arrow.svg +0 -1
- egse/icons/erase-disabled.svg +0 -19
- egse/icons/erase.svg +0 -59
- egse/icons/fitsgen-start.svg +0 -47
- egse/icons/fitsgen-stop.svg +0 -48
- egse/icons/fitsgen.svg +0 -1
- egse/icons/forward.svg +0 -1
- egse/icons/fov-hk-start.svg +0 -33
- egse/icons/fov-hk-stop.svg +0 -37
- egse/icons/fov-hk.svg +0 -1
- egse/icons/front-desk.svg +0 -1
- egse/icons/home-actioned.svg +0 -15
- egse/icons/home-disabled.svg +0 -15
- egse/icons/home.svg +0 -13
- egse/icons/info.svg +0 -1
- egse/icons/invalid.png +0 -0
- egse/icons/led-green.svg +0 -20
- egse/icons/led-grey.svg +0 -20
- egse/icons/led-orange.svg +0 -20
- egse/icons/led-red.svg +0 -20
- egse/icons/led-square-green.svg +0 -134
- egse/icons/led-square-grey.svg +0 -134
- egse/icons/led-square-orange.svg +0 -134
- egse/icons/led-square-red.svg +0 -134
- egse/icons/limit-switch-all-green.svg +0 -115
- egse/icons/limit-switch-all-red.svg +0 -117
- egse/icons/limit-switch-el+.svg +0 -116
- egse/icons/limit-switch-el-.svg +0 -117
- egse/icons/location-marker.svg +0 -1
- egse/icons/logo-dpu.svg +0 -48
- egse/icons/logo-gimbal.svg +0 -112
- egse/icons/logo-huber.svg +0 -23
- egse/icons/logo-ogse.svg +0 -31
- egse/icons/logo-puna.svg +0 -92
- egse/icons/logo-tcs.svg +0 -29
- egse/icons/logo-zonda.svg +0 -66
- egse/icons/maximize.svg +0 -1
- egse/icons/meter.svg +0 -1
- egse/icons/more.svg +0 -45
- egse/icons/n-fee-hk-start.svg +0 -24
- egse/icons/n-fee-hk-stop.svg +0 -25
- egse/icons/n-fee-hk.svg +0 -83
- egse/icons/observing-off.svg +0 -46
- egse/icons/observing-on.svg +0 -46
- egse/icons/open-document-hdf5.png +0 -0
- egse/icons/open-document-hdf5.svg +0 -21
- egse/icons/ops-mode.svg +0 -1
- egse/icons/play-green.svg +0 -17
- egse/icons/plugged-disabled.svg +0 -27
- egse/icons/plugged.svg +0 -21
- egse/icons/pm_ui.svg +0 -1
- egse/icons/power-button-green.svg +0 -27
- egse/icons/power-button-red.svg +0 -27
- egse/icons/power-button.svg +0 -27
- egse/icons/radar.svg +0 -1
- egse/icons/radioactive.svg +0 -2
- egse/icons/reload.svg +0 -1
- egse/icons/remote-control-off.svg +0 -28
- egse/icons/remote-control-on.svg +0 -28
- egse/icons/repeat-blue.svg +0 -15
- egse/icons/repeat.svg +0 -1
- egse/icons/settings.svg +0 -1
- egse/icons/shrink.svg +0 -1
- egse/icons/shutter.svg +0 -1
- egse/icons/sign-off.svg +0 -1
- egse/icons/sign-on.svg +0 -1
- egse/icons/sim-mode.svg +0 -1
- egse/icons/small-buttons-go.svg +0 -20
- egse/icons/small-buttons-minus.svg +0 -51
- egse/icons/small-buttons-plus.svg +0 -51
- egse/icons/sponge.svg +0 -220
- egse/icons/start-button-disabled.svg +0 -84
- egse/icons/start-button.svg +0 -50
- egse/icons/stop-button-disabled.svg +0 -84
- egse/icons/stop-button.svg +0 -50
- egse/icons/stop-red.svg +0 -17
- egse/icons/stop.svg +0 -1
- egse/icons/switch-disabled-square.svg +0 -87
- egse/icons/switch-disabled.svg +0 -15
- egse/icons/switch-off-square.svg +0 -87
- egse/icons/switch-off.svg +0 -72
- egse/icons/switch-on-square.svg +0 -87
- egse/icons/switch-on.svg +0 -61
- egse/icons/temperature-control.svg +0 -44
- egse/icons/th_ui_logo.svg +0 -1
- egse/icons/unplugged.svg +0 -23
- egse/icons/unvalid.png +0 -0
- egse/icons/user-interface.svg +0 -1
- egse/icons/vacuum.svg +0 -1
- egse/icons/valid.png +0 -0
- egse/icons/zoom-to-pixel-dark.svg +0 -64
- egse/icons/zoom-to-pixel-white.svg +0 -36
- egse/images/big-rotation-stage.png +0 -0
- egse/images/connected-100.png +0 -0
- egse/images/cross.svg +0 -6
- egse/images/disconnected-100.png +0 -0
- egse/images/gui-icon.png +0 -0
- egse/images/home.svg +0 -6
- egse/images/info-icon.png +0 -0
- egse/images/led-black.svg +0 -89
- egse/images/led-green.svg +0 -85
- egse/images/led-orange.svg +0 -85
- egse/images/led-red.svg +0 -85
- egse/images/load-icon.png +0 -0
- egse/images/load-setup.png +0 -0
- egse/images/load.png +0 -0
- egse/images/pause.png +0 -0
- egse/images/play-button.svg +0 -8
- egse/images/play.png +0 -0
- egse/images/process-status.png +0 -0
- egse/images/restart.png +0 -0
- egse/images/search.png +0 -0
- egse/images/sma.png +0 -0
- egse/images/start.png +0 -0
- egse/images/stop-button.svg +0 -8
- egse/images/stop.png +0 -0
- egse/images/switch-off.svg +0 -48
- egse/images/switch-on.svg +0 -48
- egse/images/undo.png +0 -0
- egse/images/update-button.svg +0 -11
- egse/imageviewer/exposureselection.py +0 -475
- egse/imageviewer/imageviewer.py +0 -198
- egse/imageviewer/matchfocalplane.py +0 -179
- egse/imageviewer/subfieldposition.py +0 -133
- egse/lampcontrol/__init__.py +0 -4
- egse/lampcontrol/beaglebone/beaglebone.py +0 -178
- egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
- egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
- egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
- egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
- egse/lampcontrol/energetiq/__init__.py +0 -22
- egse/lampcontrol/energetiq/eq99.yaml +0 -98
- egse/lampcontrol/energetiq/lampEQ99.py +0 -283
- egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
- egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
- egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
- egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
- egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
- egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
- egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
- egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
- egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
- egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
- egse/lib/ximc/libximc.framework/libbindy.so +0 -0
- egse/lib/ximc/libximc.framework/libximc +0 -0
- egse/lib/ximc/libximc.framework/libximc.so +0 -0
- egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
- egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
- egse/lib/ximc/pyximc.py +0 -922
- egse/listener.py +0 -179
- egse/logger/__init__.py +0 -243
- egse/logger/log_cs.py +0 -321
- egse/metrics.py +0 -102
- egse/mixin.py +0 -464
- egse/monitoring.py +0 -95
- egse/ni/alarms/__init__.py +0 -26
- egse/ni/alarms/cdaq9375.py +0 -300
- egse/ni/alarms/cdaq9375.yaml +0 -89
- egse/ni/alarms/cdaq9375_cs.py +0 -130
- egse/ni/alarms/cdaq9375_devif.py +0 -183
- egse/ni/alarms/cdaq9375_protocol.py +0 -48
- egse/obs_inspection.py +0 -165
- egse/observer.py +0 -41
- egse/obsid.py +0 -163
- egse/powermeter/__init__.py +0 -0
- egse/powermeter/ni/__init__.py +0 -38
- egse/powermeter/ni/cdaq9184.py +0 -224
- egse/powermeter/ni/cdaq9184.yaml +0 -73
- egse/powermeter/ni/cdaq9184_cs.py +0 -130
- egse/powermeter/ni/cdaq9184_devif.py +0 -201
- egse/powermeter/ni/cdaq9184_protocol.py +0 -48
- egse/powermeter/ni/cdaq9184_ui.py +0 -544
- egse/powermeter/thorlabs/__init__.py +0 -25
- egse/powermeter/thorlabs/pm100a.py +0 -380
- egse/powermeter/thorlabs/pm100a.yaml +0 -132
- egse/powermeter/thorlabs/pm100a_cs.py +0 -136
- egse/powermeter/thorlabs/pm100a_devif.py +0 -127
- egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
- egse/powermeter/thorlabs/pm100a_ui.py +0 -725
- egse/process.py +0 -451
- egse/procman/__init__.py +0 -834
- egse/procman/cannot_start_process_popup.py +0 -43
- egse/procman/procman.yaml +0 -49
- egse/procman/procman_cs.py +0 -201
- egse/procman/procman_ui.py +0 -2081
- egse/protocol.py +0 -605
- egse/proxy.py +0 -531
- egse/randomwalk.py +0 -140
- egse/reg.py +0 -585
- egse/reload.py +0 -122
- egse/reprocess.py +0 -693
- egse/resource.py +0 -333
- egse/rmap.py +0 -406
- egse/rst.py +0 -135
- egse/search.py +0 -182
- egse/serialdevice.py +0 -190
- egse/services.py +0 -247
- egse/services.yaml +0 -68
- egse/settings.py +0 -379
- egse/settings.yaml +0 -980
- egse/setup.py +0 -1181
- egse/shutter/__init__.py +0 -0
- egse/shutter/thorlabs/__init__.py +0 -19
- egse/shutter/thorlabs/ksc101.py +0 -205
- egse/shutter/thorlabs/ksc101.yaml +0 -105
- egse/shutter/thorlabs/ksc101_cs.py +0 -136
- egse/shutter/thorlabs/ksc101_devif.py +0 -201
- egse/shutter/thorlabs/ksc101_protocol.py +0 -71
- egse/shutter/thorlabs/ksc101_ui.py +0 -548
- egse/shutter/thorlabs/sc10.py +0 -82
- egse/shutter/thorlabs/sc10.yaml +0 -52
- egse/shutter/thorlabs/sc10_controller.py +0 -81
- egse/shutter/thorlabs/sc10_cs.py +0 -108
- egse/shutter/thorlabs/sc10_interface.py +0 -25
- egse/shutter/thorlabs/sc10_simulator.py +0 -30
- egse/simulator.py +0 -41
- egse/slack.py +0 -61
- egse/socketdevice.py +0 -218
- egse/sockets.py +0 -218
- egse/spw.py +0 -1401
- egse/stages/__init__.py +0 -12
- egse/stages/aerotech/ensemble.py +0 -245
- egse/stages/aerotech/ensemble.yaml +0 -205
- egse/stages/aerotech/ensemble_controller.py +0 -275
- egse/stages/aerotech/ensemble_cs.py +0 -110
- egse/stages/aerotech/ensemble_interface.py +0 -132
- egse/stages/aerotech/ensemble_parameters.py +0 -433
- egse/stages/aerotech/ensemble_simulator.py +0 -27
- egse/stages/aerotech/mgse_sim.py +0 -188
- egse/stages/arun/smd3.py +0 -110
- egse/stages/arun/smd3.yaml +0 -68
- egse/stages/arun/smd3_controller.py +0 -470
- egse/stages/arun/smd3_cs.py +0 -112
- egse/stages/arun/smd3_interface.py +0 -53
- egse/stages/arun/smd3_simulator.py +0 -27
- egse/stages/arun/smd3_stop.py +0 -16
- egse/stages/huber/__init__.py +0 -49
- egse/stages/huber/smc9300.py +0 -920
- egse/stages/huber/smc9300.yaml +0 -63
- egse/stages/huber/smc9300_cs.py +0 -178
- egse/stages/huber/smc9300_devif.py +0 -345
- egse/stages/huber/smc9300_protocol.py +0 -113
- egse/stages/huber/smc9300_sim.py +0 -547
- egse/stages/huber/smc9300_ui.py +0 -973
- egse/state.py +0 -173
- egse/statemachine.py +0 -274
- egse/storage/__init__.py +0 -1067
- egse/storage/persistence.py +0 -2295
- egse/storage/storage.yaml +0 -79
- egse/storage/storage_cs.py +0 -231
- egse/styles/dark.qss +0 -343
- egse/styles/default.qss +0 -48
- egse/synoptics/__init__.py +0 -417
- egse/synoptics/syn.yaml +0 -9
- egse/synoptics/syn_cs.py +0 -195
- egse/system.py +0 -1611
- egse/tcs/__init__.py +0 -14
- egse/tcs/tcs.py +0 -879
- egse/tcs/tcs.yaml +0 -14
- egse/tcs/tcs_cs.py +0 -202
- egse/tcs/tcs_devif.py +0 -292
- egse/tcs/tcs_protocol.py +0 -180
- egse/tcs/tcs_sim.py +0 -177
- egse/tcs/tcs_ui.py +0 -543
- egse/tdms.py +0 -171
- egse/tempcontrol/__init__.py +0 -23
- egse/tempcontrol/agilent/agilent34970.py +0 -109
- egse/tempcontrol/agilent/agilent34970.yaml +0 -44
- egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
- egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
- egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
- egse/tempcontrol/agilent/agilent34972.py +0 -111
- egse/tempcontrol/agilent/agilent34972.yaml +0 -44
- egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
- egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
- egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
- egse/tempcontrol/beaglebone/beaglebone.py +0 -341
- egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
- egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
- egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
- egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
- egse/tempcontrol/digalox/digalox.py +0 -115
- egse/tempcontrol/digalox/digalox.yaml +0 -36
- egse/tempcontrol/digalox/digalox_cs.py +0 -108
- egse/tempcontrol/digalox/digalox_protocol.py +0 -56
- egse/tempcontrol/keithley/__init__.py +0 -33
- egse/tempcontrol/keithley/daq6510.py +0 -662
- egse/tempcontrol/keithley/daq6510.yaml +0 -105
- egse/tempcontrol/keithley/daq6510_cs.py +0 -163
- egse/tempcontrol/keithley/daq6510_devif.py +0 -343
- egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
- egse/tempcontrol/keithley/daq6510_sim.py +0 -186
- egse/tempcontrol/lakeshore/__init__.py +0 -33
- egse/tempcontrol/lakeshore/lsci.py +0 -361
- egse/tempcontrol/lakeshore/lsci.yaml +0 -162
- egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
- egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
- egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
- egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
- egse/tempcontrol/ni/__init__.py +0 -0
- egse/tempcontrol/spid/spid.py +0 -109
- egse/tempcontrol/spid/spid.yaml +0 -81
- egse/tempcontrol/spid/spid_controller.py +0 -279
- egse/tempcontrol/spid/spid_cs.py +0 -136
- egse/tempcontrol/spid/spid_protocol.py +0 -107
- egse/tempcontrol/spid/spid_ui.py +0 -723
- egse/tempcontrol/srs/__init__.py +0 -22
- egse/tempcontrol/srs/ptc10.py +0 -867
- egse/tempcontrol/srs/ptc10.yaml +0 -227
- egse/tempcontrol/srs/ptc10_cs.py +0 -128
- egse/tempcontrol/srs/ptc10_devif.py +0 -116
- egse/tempcontrol/srs/ptc10_protocol.py +0 -39
- egse/tempcontrol/srs/ptc10_ui.py +0 -906
- egse/ups/apc/apc.py +0 -236
- egse/ups/apc/apc.yaml +0 -45
- egse/ups/apc/apc_cs.py +0 -101
- egse/ups/apc/apc_protocol.py +0 -125
- egse/user.yaml +0 -7
- egse/vacuum/beaglebone/beaglebone.py +0 -149
- egse/vacuum/beaglebone/beaglebone.yaml +0 -44
- egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
- egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
- egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
- egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
- egse/vacuum/instrutech/igm402.py +0 -91
- egse/vacuum/instrutech/igm402.yaml +0 -90
- egse/vacuum/instrutech/igm402_controller.py +0 -124
- egse/vacuum/instrutech/igm402_cs.py +0 -108
- egse/vacuum/instrutech/igm402_interface.py +0 -49
- egse/vacuum/instrutech/igm402_simulator.py +0 -36
- egse/vacuum/keller/kellerBus.py +0 -256
- egse/vacuum/keller/leo3.py +0 -100
- egse/vacuum/keller/leo3.yaml +0 -38
- egse/vacuum/keller/leo3_controller.py +0 -81
- egse/vacuum/keller/leo3_cs.py +0 -101
- egse/vacuum/keller/leo3_interface.py +0 -33
- egse/vacuum/mks/evision.py +0 -86
- egse/vacuum/mks/evision.yaml +0 -75
- egse/vacuum/mks/evision_cs.py +0 -101
- egse/vacuum/mks/evision_devif.py +0 -313
- egse/vacuum/mks/evision_interface.py +0 -60
- egse/vacuum/mks/evision_simulator.py +0 -24
- egse/vacuum/mks/evision_ui.py +0 -701
- egse/vacuum/pfeiffer/acp40.py +0 -87
- egse/vacuum/pfeiffer/acp40.yaml +0 -60
- egse/vacuum/pfeiffer/acp40_controller.py +0 -117
- egse/vacuum/pfeiffer/acp40_cs.py +0 -109
- egse/vacuum/pfeiffer/acp40_interface.py +0 -40
- egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
- egse/vacuum/pfeiffer/tc400.py +0 -87
- egse/vacuum/pfeiffer/tc400.yaml +0 -83
- egse/vacuum/pfeiffer/tc400_controller.py +0 -136
- egse/vacuum/pfeiffer/tc400_cs.py +0 -109
- egse/vacuum/pfeiffer/tc400_interface.py +0 -70
- egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
- egse/vacuum/pfeiffer/tpg261.py +0 -80
- egse/vacuum/pfeiffer/tpg261.yaml +0 -66
- egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
- egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
- egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
- egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
- egse/version.py +0 -174
- egse/visitedpositions.py +0 -398
- egse/windowing.py +0 -213
- egse/zmq/__init__.py +0 -28
- egse/zmq/spw.py +0 -160
- egse/zmq_ser.py +0 -41
- scripts/alerts/cold.yaml +0 -278
- scripts/alerts/example_alerts.yaml +0 -54
- scripts/alerts/transition.yaml +0 -14
- scripts/alerts/warm.yaml +0 -49
- scripts/analyse_n_fee_hk_data.py +0 -52
- scripts/check_hdf5_files.py +0 -192
- scripts/check_register_sync.py +0 -47
- scripts/check_tcs_calib_coef.py +0 -90
- scripts/correct_ccd_cold_temperature_cal.py +0 -157
- scripts/create_hdf5_report.py +0 -293
- scripts/csl_model.py +0 -420
- scripts/csl_restore_setup.py +0 -229
- scripts/export-grafana-dashboards.py +0 -49
- scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
- scripts/fdir/fdir_table.yaml +0 -70
- scripts/fdir/fdir_test_recovery.py +0 -10
- scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
- scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
- scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
- scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
- scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
- scripts/fix_csv.py +0 -80
- scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
- scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
- scripts/ias/correct_trp_swap_achel.py +0 -199
- scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
- scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
- scripts/n_fee_supply_voltage_calculation.py +0 -92
- scripts/playground.py +0 -30
- scripts/print_hdf5_hk_data.py +0 -68
- scripts/print_register_map.py +0 -43
- scripts/remove_lines_between_matches.py +0 -188
- scripts/sron/commanding/control_heaters.py +0 -44
- scripts/sron/commanding/pumpdown.py +0 -46
- scripts/sron/commanding/set_pid_setpoint.py +0 -19
- scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
- scripts/sron/commanding/shutdown_pumps.py +0 -33
- scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
- scripts/sron/correct_trp_swap_brigand.py +0 -204
- scripts/sron/gimbal_conversions.py +0 -75
- scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
- scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
- scripts/sron/tm_gen/tm_gen_spid.py +0 -13
- scripts/update_operational_cgse.py +0 -268
- scripts/update_operational_cgse_old.py +0 -273
egse/gimbal/symetrie/gimbal.py
DELETED
|
@@ -1,877 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module defines the device classes to be used to connect to and control the Gimbal from
|
|
3
|
-
Symétrie.
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
from cmath import nan
|
|
7
|
-
import logging
|
|
8
|
-
import math
|
|
9
|
-
import time
|
|
10
|
-
from datetime import datetime
|
|
11
|
-
from datetime import timedelta
|
|
12
|
-
|
|
13
|
-
import numpy as np
|
|
14
|
-
|
|
15
|
-
from egse.bits import set_bit
|
|
16
|
-
from egse.coordinates.referenceFrame import ReferenceFrame
|
|
17
|
-
from egse.device import DeviceConnectionState
|
|
18
|
-
from egse.device import DeviceInterface
|
|
19
|
-
from egse.gimbal import GimbalError
|
|
20
|
-
from egse.gimbal.symetrie import pmac
|
|
21
|
-
from egse.gimbal.symetrie.alpha import AlphaControllerInterface
|
|
22
|
-
from egse.gimbal.symetrie.pmac import PMACError
|
|
23
|
-
from egse.gimbal.symetrie.pmac import PmacEthernetInterface
|
|
24
|
-
from egse.gimbal.symetrie.pmac import decode_Q29
|
|
25
|
-
from egse.gimbal.symetrie.pmac import decode_Q36
|
|
26
|
-
from egse.proxy import Proxy
|
|
27
|
-
from egse.settings import Settings
|
|
28
|
-
from egse.zmq_ser import connect_address
|
|
29
|
-
|
|
30
|
-
logger = logging.getLogger(__name__)
|
|
31
|
-
|
|
32
|
-
GIMBAL_SETTINGS = Settings.load("Gimbal Controller")
|
|
33
|
-
CTRL_SETTINGS = Settings.load("Gimbal Control Server")
|
|
34
|
-
DEVICE_SETTINGS = Settings.load(filename="gimbal.yaml")
|
|
35
|
-
|
|
36
|
-
NUM_OF_DECIMALS = 6 # used for rounding numbers before sending to PMAC
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class GimbalInterface(AlphaControllerInterface, DeviceInterface):
|
|
40
|
-
"""
|
|
41
|
-
Interface definition for the GimbalController, the GimbalProxy and the GimbalSimulator.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class GimbalController(GimbalInterface):
|
|
46
|
-
"""
|
|
47
|
-
The GimbalController class allows controlling a Symétrie Gimbal through an Ethernet
|
|
48
|
-
interface that is connecting a Symétrie Controller.
|
|
49
|
-
|
|
50
|
-
The Symétrie Controller can be either in simulation mode or have a real Gimbal
|
|
51
|
-
connected.
|
|
52
|
-
|
|
53
|
-
**Synopsis**
|
|
54
|
-
|
|
55
|
-
from egse.gimbal.symetrie.gimbal import GimbalController
|
|
56
|
-
gimbal = GimbalController(hostname="10.33.178.145", port=1025)
|
|
57
|
-
try:
|
|
58
|
-
gimbal.connect()
|
|
59
|
-
|
|
60
|
-
# do some useful things here with the gimbal
|
|
61
|
-
|
|
62
|
-
except GimbalError as exc:
|
|
63
|
-
print(exc)
|
|
64
|
-
finally:
|
|
65
|
-
gimbal.disconnect()
|
|
66
|
-
|
|
67
|
-
The constructor also sets the connection parameters and tries to connect
|
|
68
|
-
to the controller. Make sure that you explicitly use the gimbal.disconnect()
|
|
69
|
-
command when no connection is needed anymore.
|
|
70
|
-
|
|
71
|
-
The controller can also be used as a context manager, in which case the `connect()`
|
|
72
|
-
and `disconnect()` methods should not be called:
|
|
73
|
-
|
|
74
|
-
with GimbalController() as gimbal:
|
|
75
|
-
gimbal.info()
|
|
76
|
-
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
SPEC_POS_MACHINE_ZERO = 0
|
|
80
|
-
"""Gimbal machine zero, for maintenance or Jog only."""
|
|
81
|
-
SPEC_POS_USER_ZERO = 2
|
|
82
|
-
"""Gimbal user zero position."""
|
|
83
|
-
|
|
84
|
-
def __init__(self, hostname=GIMBAL_SETTINGS.HOSTNAME, port=GIMBAL_SETTINGS.PORT):
|
|
85
|
-
"""
|
|
86
|
-
Opens a TCP/IP socket connection with the Gimbal Hardware Controller.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
hostname (str): the IP address or fully qualified hostname of the Gimbal hardware
|
|
90
|
-
controller.
|
|
91
|
-
The default is defined in the ``settings.yaml`` configuration file.
|
|
92
|
-
|
|
93
|
-
port (int): the IP port number to connect to, by default set in the ``settings.yaml``
|
|
94
|
-
configuration file.
|
|
95
|
-
|
|
96
|
-
Raises:
|
|
97
|
-
GimbalError: when the connection could not be established for some reason.
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
super().__init__()
|
|
101
|
-
|
|
102
|
-
logger.debug(f"Initializing GimbalController with hostname={hostname} on port={port}")
|
|
103
|
-
|
|
104
|
-
try:
|
|
105
|
-
self.pmac = PmacEthernetInterface()
|
|
106
|
-
self.pmac.setConnectionParameters(hostname, port)
|
|
107
|
-
except PMACError as exc:
|
|
108
|
-
logger.warning(
|
|
109
|
-
f"GimbalError: Couldn't establish connection with the Gimbal Hardware "
|
|
110
|
-
f"Controller: ({exc})"
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
def is_simulator(self):
|
|
114
|
-
return False
|
|
115
|
-
|
|
116
|
-
def is_connected(self):
|
|
117
|
-
return self.pmac.isConnected()
|
|
118
|
-
|
|
119
|
-
def connect(self):
|
|
120
|
-
try:
|
|
121
|
-
self.pmac.connect()
|
|
122
|
-
except PMACError as exc:
|
|
123
|
-
logger.warning(f"PMACError caught: Couldn't establish connection ({exc})")
|
|
124
|
-
raise ConnectionError("Couldn't establish a connection with the Gimbal.") from exc
|
|
125
|
-
|
|
126
|
-
self.notify_observers(DeviceConnectionState.DEVICE_CONNECTED)
|
|
127
|
-
|
|
128
|
-
def disconnect(self):
|
|
129
|
-
try:
|
|
130
|
-
self.pmac.disconnect()
|
|
131
|
-
except PMACError as exc:
|
|
132
|
-
raise ConnectionError("Couldn't disconnect from Gimbal.") from exc
|
|
133
|
-
|
|
134
|
-
self.notify_observers(DeviceConnectionState.DEVICE_NOT_CONNECTED)
|
|
135
|
-
|
|
136
|
-
def reconnect(self):
|
|
137
|
-
if self.is_connected():
|
|
138
|
-
self.disconnect()
|
|
139
|
-
self.connect()
|
|
140
|
-
|
|
141
|
-
def is_in_position(self):
|
|
142
|
-
try:
|
|
143
|
-
out = self.pmac.getQVars(36, [0], int)
|
|
144
|
-
except PMACError as exc:
|
|
145
|
-
raise GimbalError(
|
|
146
|
-
"Couldn't retrieve information from Gimbal Hardware Controller.") from exc
|
|
147
|
-
return bool(out[0] & 0x04)
|
|
148
|
-
|
|
149
|
-
def info(self):
|
|
150
|
-
try:
|
|
151
|
-
msg = "Info about the Gimbal:\n"
|
|
152
|
-
msg += f"model = {self.pmac.getPmacModel()}\n"
|
|
153
|
-
msg += f"CID = {self.pmac.getCID()}\n"
|
|
154
|
-
msg += f"version = {self.pmac.getVersion()}\n"
|
|
155
|
-
msg += f"cpu = {self.pmac.getCPU()}\n"
|
|
156
|
-
msg += f"type = {self.pmac.getType()}\n"
|
|
157
|
-
msg += f"vendorID= {self.pmac.getVID()}\n"
|
|
158
|
-
msg += f"date = {self.pmac.getDate()}\n"
|
|
159
|
-
msg += f"time = {self.pmac.getTime()}\n"
|
|
160
|
-
msg += f"today = {self.pmac.getToday()}\n"
|
|
161
|
-
except PMACError as exc:
|
|
162
|
-
raise GimbalError(
|
|
163
|
-
"Couldn't retrieve information from Gimbal Hardware Controller."
|
|
164
|
-
) from exc
|
|
165
|
-
|
|
166
|
-
return msg
|
|
167
|
-
|
|
168
|
-
def stop(self):
|
|
169
|
-
try:
|
|
170
|
-
rc = self.pmac.sendCommand(pmac.CMD_STOP)
|
|
171
|
-
except PMACError as exc:
|
|
172
|
-
raise GimbalError("Couldn't complete the STOP command.") from exc
|
|
173
|
-
|
|
174
|
-
return rc
|
|
175
|
-
|
|
176
|
-
def homing(self):
|
|
177
|
-
try:
|
|
178
|
-
rc = self.pmac.sendCommand(pmac.CMD_HOMING)
|
|
179
|
-
except PMACError as exc:
|
|
180
|
-
raise GimbalError("Couldn't complete the HOMING command.") from exc
|
|
181
|
-
|
|
182
|
-
logger.info("Homing: Command was successful")
|
|
183
|
-
|
|
184
|
-
return rc
|
|
185
|
-
|
|
186
|
-
def is_homing_done(self):
|
|
187
|
-
try:
|
|
188
|
-
rc = self.pmac.getQVars(26, [0], int)[0]
|
|
189
|
-
except PMACError as pmac_exc:
|
|
190
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
191
|
-
return False
|
|
192
|
-
|
|
193
|
-
msg = { # noqa: F841
|
|
194
|
-
0: "Homing status is undefined.",
|
|
195
|
-
1: "Homing is in progress",
|
|
196
|
-
2: "Homing is done",
|
|
197
|
-
3: "An error occurred during the Homing process.",
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if rc == 2:
|
|
201
|
-
return True
|
|
202
|
-
|
|
203
|
-
return False
|
|
204
|
-
|
|
205
|
-
def activate_control_loop(self):
|
|
206
|
-
try:
|
|
207
|
-
rc = self.pmac.sendCommand(pmac.CMD_CONTROLON)
|
|
208
|
-
except PMACError as exc:
|
|
209
|
-
raise GimbalError("Couldn't activate the control loop.") from exc
|
|
210
|
-
|
|
211
|
-
msg = { # noqa: F841
|
|
212
|
-
0: "Command was successful",
|
|
213
|
-
-1: "Command was ignored",
|
|
214
|
-
-2: "Control of the servo motors has failed",
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return rc
|
|
218
|
-
|
|
219
|
-
def deactivate_control_loop(self):
|
|
220
|
-
try:
|
|
221
|
-
rc = self.pmac.sendCommand(pmac.CMD_CONTROLOFF)
|
|
222
|
-
except PMACError as exc:
|
|
223
|
-
raise GimbalError("Couldn't de-activate the control loop.") from exc
|
|
224
|
-
|
|
225
|
-
return rc
|
|
226
|
-
|
|
227
|
-
def __move(self, cm, grx, gry):
|
|
228
|
-
"""
|
|
229
|
-
Ask the controller to perform the movement defined by the arguments.
|
|
230
|
-
|
|
231
|
-
For all control modes cm, the rotation centre coincides with the Object
|
|
232
|
-
Coordinates System origin and the movements are controlled with translation
|
|
233
|
-
components at first (Tx, Ty, tZ) and then the rotation components (Rx, Ry, Rz).
|
|
234
|
-
|
|
235
|
-
Control mode cm:
|
|
236
|
-
* 0 = absolute control, object coordinate system position and orientation
|
|
237
|
-
expressed in the invariant user coordinate system
|
|
238
|
-
* 1 = user relative, motion expressed in the Object Coordinate System
|
|
239
|
-
|
|
240
|
-
Args:
|
|
241
|
-
cm (int): control mode
|
|
242
|
-
grx (float): rotation around the X-axis [deg]
|
|
243
|
-
gry (float): rotation around the Y-axis [deg]
|
|
244
|
-
|
|
245
|
-
Returns:
|
|
246
|
-
0 on success, -1 when ignored, -2 on error.
|
|
247
|
-
|
|
248
|
-
Raises:
|
|
249
|
-
PMACError: when the arguments do not match up or when there is a time out or when
|
|
250
|
-
there is a socket
|
|
251
|
-
communication error.
|
|
252
|
-
|
|
253
|
-
.. note:: When the command was not successful, this method will query the ``POSVALID?``
|
|
254
|
-
using the checkAbsolutePosition() and print a summary of the error messages
|
|
255
|
-
to the log file.
|
|
256
|
-
"""
|
|
257
|
-
rc = self.pmac.sendCommand(pmac.CMD_MOVE, cm=cm, grx=grx, gry=gry)
|
|
258
|
-
|
|
259
|
-
error_code_msg = {
|
|
260
|
-
0: "Command was successful",
|
|
261
|
-
-1: "Command was ignored",
|
|
262
|
-
-2: "Command was invalid, check with POSVALID?",
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if rc < 0:
|
|
266
|
-
msg = f"Move command returned ({rc}: {error_code_msg[rc]})."
|
|
267
|
-
|
|
268
|
-
if rc == -2:
|
|
269
|
-
Q29, errors = self.__check_movement(cm, grx, gry)
|
|
270
|
-
|
|
271
|
-
msg += "\nError messages returned from POSVALID?:\n"
|
|
272
|
-
for key, value in errors.items():
|
|
273
|
-
msg += f" bit {key:<2d}: {value}\n"
|
|
274
|
-
|
|
275
|
-
logger.debug(msg)
|
|
276
|
-
|
|
277
|
-
return rc
|
|
278
|
-
|
|
279
|
-
def __check_movement(self, cm, grx, gry):
|
|
280
|
-
"""
|
|
281
|
-
Ask the controller if the movement defined by the arguments is feasible.
|
|
282
|
-
|
|
283
|
-
Returns a tuple where the first element is an integer that represents the
|
|
284
|
-
bitfield encoding the errors. The second element is a dictionary with the
|
|
285
|
-
bit numbers that were (on) and the corresponding error description.
|
|
286
|
-
|
|
287
|
-
Args:
|
|
288
|
-
grx (float): rotation around the X-axis [deg]
|
|
289
|
-
gry (float): rotation around the Y-axis [deg]
|
|
290
|
-
|
|
291
|
-
"""
|
|
292
|
-
out = self.pmac.sendCommand(pmac.CMD_POSVALID_GET, cm=cm, grx=grx, gry=gry)
|
|
293
|
-
|
|
294
|
-
Q29 = decode_Q29(out[0])
|
|
295
|
-
return out[0], Q29
|
|
296
|
-
|
|
297
|
-
def move_absolute(self, grx, gry):
|
|
298
|
-
try:
|
|
299
|
-
rc = self.__move(0, grx, gry)
|
|
300
|
-
except PMACError as exc:
|
|
301
|
-
raise GimbalError("Couldn't execute the moveAbsolute command.") from exc
|
|
302
|
-
|
|
303
|
-
return rc
|
|
304
|
-
|
|
305
|
-
def check_absolute_movement(self, grx, gry):
|
|
306
|
-
return self.__check_movement(0, grx, gry)
|
|
307
|
-
|
|
308
|
-
def move_relative(self, grx, gry):
|
|
309
|
-
try:
|
|
310
|
-
rc = self.__move(10, grx, gry)
|
|
311
|
-
except PMACError as exc:
|
|
312
|
-
raise GimbalError("Couldn't execute the relative movement [user] command.") from exc
|
|
313
|
-
|
|
314
|
-
return rc
|
|
315
|
-
|
|
316
|
-
def check_relative_movement(self, grx, gry):
|
|
317
|
-
return self.__check_movement(10, grx, gry)
|
|
318
|
-
|
|
319
|
-
def perform_maintenance(self, axis):
|
|
320
|
-
try:
|
|
321
|
-
rc = self.pmac.sendCommand(pmac.CMD_MAINTENANCE, axis=axis)
|
|
322
|
-
except PMACError as exc:
|
|
323
|
-
raise GimbalError("Couldn't perform maintenance cycle.") from exc
|
|
324
|
-
|
|
325
|
-
msg = {0: "Command was successfully executed", -1: "Command was ignored"} # noqa: F841
|
|
326
|
-
|
|
327
|
-
return rc
|
|
328
|
-
|
|
329
|
-
def goto_specific_position(self, pos):
|
|
330
|
-
try:
|
|
331
|
-
rc = self.pmac.sendCommand(pmac.CMD_SPECIFICPOS, pos=pos)
|
|
332
|
-
except PMACError as exc:
|
|
333
|
-
raise GimbalError(f"Couldn't goto specific position [pos={pos}].") from exc
|
|
334
|
-
|
|
335
|
-
msg = {
|
|
336
|
-
0: "Command was successfully executed",
|
|
337
|
-
-1: "Command was ignored",
|
|
338
|
-
-2: "Invalid movement command",
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
logger.info(f"Goto Specific Position [{pos}]: {msg[rc]}")
|
|
342
|
-
|
|
343
|
-
if rc < 0:
|
|
344
|
-
try:
|
|
345
|
-
out = self.pmac.getQVars(0, [29], int)
|
|
346
|
-
except PMACError as exc:
|
|
347
|
-
raise GimbalError("Couldn't get a response from the Gimbal controller.") from exc
|
|
348
|
-
Q29 = decode_Q29(out[0])
|
|
349
|
-
|
|
350
|
-
msg = "Error messages returned in Q29:\n"
|
|
351
|
-
for key, value in Q29.items():
|
|
352
|
-
msg += f" {key:2d}: {value}\n"
|
|
353
|
-
|
|
354
|
-
logger.debug(msg)
|
|
355
|
-
|
|
356
|
-
return rc
|
|
357
|
-
|
|
358
|
-
def goto_zero_position(self):
|
|
359
|
-
try:
|
|
360
|
-
rc = self.pmac.sendCommand(pmac.CMD_SPECIFICPOS, pos=self.SPEC_POS_USER_ZERO)
|
|
361
|
-
except PMACError as exc:
|
|
362
|
-
raise GimbalError("Couldn't goto user zero position.") from exc
|
|
363
|
-
|
|
364
|
-
msg = {
|
|
365
|
-
0: "Command was successfully executed",
|
|
366
|
-
-1: "Command was ignored",
|
|
367
|
-
-2: "Invalid movement command",
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
logger.info(f"Goto User Zero Position [2]: {msg[rc]}")
|
|
371
|
-
|
|
372
|
-
if rc < 0:
|
|
373
|
-
try:
|
|
374
|
-
out = self.pmac.getQVars(0, [29], int)
|
|
375
|
-
except PMACError as exc:
|
|
376
|
-
raise GimbalError("Couldn't get a response from the Gimbal controller.") from exc
|
|
377
|
-
Q29 = decode_Q29(out[0])
|
|
378
|
-
|
|
379
|
-
msg = "Error messages returned in Q29:\n"
|
|
380
|
-
for key, value in Q29.items():
|
|
381
|
-
msg += f" {key:2d}: {value}\n"
|
|
382
|
-
|
|
383
|
-
logger.debug(msg)
|
|
384
|
-
|
|
385
|
-
return rc
|
|
386
|
-
|
|
387
|
-
def get_buffer(self):
|
|
388
|
-
return_string = self.pmac.getBuffer()
|
|
389
|
-
return return_string
|
|
390
|
-
|
|
391
|
-
def clear_error(self):
|
|
392
|
-
try:
|
|
393
|
-
rc = self.pmac.sendCommand(pmac.CMD_CLEARERROR)
|
|
394
|
-
except PMACError as exc:
|
|
395
|
-
raise GimbalError("Couldn't clear errors in the controller software.") from exc
|
|
396
|
-
|
|
397
|
-
return rc
|
|
398
|
-
|
|
399
|
-
def jog(self, axis: int, inc: float) -> int:
|
|
400
|
-
if not (1 <= axis <= 2):
|
|
401
|
-
logger.error(f"The axis argument must be 1 <= axis <= 2, given {axis}.")
|
|
402
|
-
raise GimbalError("Illegal Argument Value: axis is {axis}, should be 1 <= axis <= 2.")
|
|
403
|
-
|
|
404
|
-
try:
|
|
405
|
-
rc = self.pmac.sendCommand(pmac.CMD_JOG, axis=axis, inc=inc)
|
|
406
|
-
except PMACError as exc:
|
|
407
|
-
raise GimbalError(
|
|
408
|
-
f"Couldn't execute the jog command for axis={axis} with inc={inc} [deg]."
|
|
409
|
-
) from exc
|
|
410
|
-
|
|
411
|
-
msg = {0: "Command was successfully executed", -1: "Command was ignored"}
|
|
412
|
-
|
|
413
|
-
logger.info(f"JOG on axis [{axis}] of {inc} deg: {msg[rc]}")
|
|
414
|
-
|
|
415
|
-
return rc
|
|
416
|
-
|
|
417
|
-
def configure_offsets(self, grx, gry):
|
|
418
|
-
try:
|
|
419
|
-
|
|
420
|
-
rc = self.pmac.sendCommand(
|
|
421
|
-
pmac.CMD_CFG_OFFSET,
|
|
422
|
-
grx = round(grx, NUM_OF_DECIMALS),
|
|
423
|
-
gry = round(gry, NUM_OF_DECIMALS))
|
|
424
|
-
except PMACError as exc:
|
|
425
|
-
raise GimbalError(
|
|
426
|
-
"Couldn't configure coordinate systems on the gimbal controller."
|
|
427
|
-
) from exc
|
|
428
|
-
|
|
429
|
-
return rc
|
|
430
|
-
|
|
431
|
-
def get_offsets(self):
|
|
432
|
-
try:
|
|
433
|
-
out = self.pmac.sendCommand(pmac.CMD_CFG_OFFSET_GET)
|
|
434
|
-
except PMACError as exc:
|
|
435
|
-
raise GimbalError(
|
|
436
|
-
"Couldn't get the coordinate systems information from the gimbal controller."
|
|
437
|
-
) from exc
|
|
438
|
-
|
|
439
|
-
return out
|
|
440
|
-
|
|
441
|
-
def get_debug_info(self):
|
|
442
|
-
try:
|
|
443
|
-
out = self.pmac.sendCommand(pmac.CMD_STATE_DEBUG_GET)
|
|
444
|
-
except PMACError as exc:
|
|
445
|
-
raise GimbalError(
|
|
446
|
-
"Couldn't get the debugging information from the gimbal controller."
|
|
447
|
-
) from exc
|
|
448
|
-
|
|
449
|
-
return out
|
|
450
|
-
|
|
451
|
-
def set_speed(self, sr):
|
|
452
|
-
try:
|
|
453
|
-
rc = self.pmac.sendCommand(pmac.CMD_CFG_SPEED, sr=sr)
|
|
454
|
-
except PMACError as exc:
|
|
455
|
-
raise GimbalError(
|
|
456
|
-
"Couldn't set the speed for rotation [{sr} deg/s]."
|
|
457
|
-
) from exc
|
|
458
|
-
|
|
459
|
-
return rc
|
|
460
|
-
|
|
461
|
-
def get_speed(self):
|
|
462
|
-
try:
|
|
463
|
-
out = self.pmac.sendCommand(pmac.CMD_CFG_SPEED_GET)
|
|
464
|
-
except PMACError as exc:
|
|
465
|
-
raise GimbalError(
|
|
466
|
-
"Couldn't get the speed settings from the gimbal controller."
|
|
467
|
-
) from exc
|
|
468
|
-
|
|
469
|
-
return out
|
|
470
|
-
|
|
471
|
-
def get_general_state(self):
|
|
472
|
-
try:
|
|
473
|
-
out = self.pmac.getQVars(36, [0], int)
|
|
474
|
-
except PMACError as pmac_exc:
|
|
475
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
476
|
-
return None
|
|
477
|
-
|
|
478
|
-
return out[0], pmac.decode_Q36(out[0])
|
|
479
|
-
|
|
480
|
-
def get_actuator_state(self):
|
|
481
|
-
try:
|
|
482
|
-
out = self.pmac.getQVars(30, [0, 1], int)
|
|
483
|
-
except PMACError as pmac_exc:
|
|
484
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
485
|
-
return None
|
|
486
|
-
|
|
487
|
-
return [pmac.decode_Q30(value) for value in out]
|
|
488
|
-
|
|
489
|
-
def get_user_positions(self):
|
|
490
|
-
try:
|
|
491
|
-
out = self.pmac.sendCommand(pmac.CMD_POSUSER_GET)
|
|
492
|
-
except PMACError as pmac_exc:
|
|
493
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
494
|
-
return None
|
|
495
|
-
|
|
496
|
-
return out
|
|
497
|
-
|
|
498
|
-
def get_machine_positions(self):
|
|
499
|
-
try:
|
|
500
|
-
out = self.pmac.getQVars(47, [0, 1], float)
|
|
501
|
-
except PMACError as pmac_exc:
|
|
502
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
503
|
-
return None
|
|
504
|
-
|
|
505
|
-
return out
|
|
506
|
-
|
|
507
|
-
def get_actuator_length(self):
|
|
508
|
-
try:
|
|
509
|
-
out = self.pmac.getQVars(41, [0, 1], float)
|
|
510
|
-
except PMACError as pmac_exc:
|
|
511
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
512
|
-
return None
|
|
513
|
-
|
|
514
|
-
return out
|
|
515
|
-
|
|
516
|
-
def get_motor_temperatures(self):
|
|
517
|
-
try:
|
|
518
|
-
out = self.pmac.sendCommand(pmac.CMD_STATE_AI_GET)
|
|
519
|
-
except PMACError as pmac_exc:
|
|
520
|
-
logger.error(f"PMAC Exception: {pmac_exc}", exc_info=True)
|
|
521
|
-
return None
|
|
522
|
-
|
|
523
|
-
return out
|
|
524
|
-
|
|
525
|
-
def reset(self, wait=True, verbose=False):
|
|
526
|
-
try:
|
|
527
|
-
self.pmac.sendCommand(pmac.CMD_RESETSOFT)
|
|
528
|
-
except PMACError as exc:
|
|
529
|
-
raise GimbalError("Couldn't (soft) reset the gimbal controller.") from exc
|
|
530
|
-
|
|
531
|
-
# How do I know when the RESETSOFT has finished and we can send further commands?
|
|
532
|
-
|
|
533
|
-
if wait:
|
|
534
|
-
logger.info("Sent a soft reset, this will take about 30 seconds to complete.")
|
|
535
|
-
self.__wait(30, verbose=verbose)
|
|
536
|
-
|
|
537
|
-
def __wait(self, duration, verbose=False):
|
|
538
|
-
"""
|
|
539
|
-
Wait for a specific duration in seconds.
|
|
540
|
-
"""
|
|
541
|
-
_timeout = timedelta(seconds=duration)
|
|
542
|
-
_start = datetime.now()
|
|
543
|
-
|
|
544
|
-
_rate = timedelta(seconds=5) # every _rate seconds print a message
|
|
545
|
-
_count = 0
|
|
546
|
-
|
|
547
|
-
logger.info(f"Just waiting {duration} seconds ...")
|
|
548
|
-
|
|
549
|
-
while datetime.now() - _start < _timeout:
|
|
550
|
-
|
|
551
|
-
if verbose and (datetime.now() - _start > _count * _rate):
|
|
552
|
-
_count += 1
|
|
553
|
-
logger.info(f"waited for {_count * _rate} of {_timeout} seconds, ")
|
|
554
|
-
print(f"waited for {_count * _rate} of {_timeout} seconds, ")
|
|
555
|
-
|
|
556
|
-
time.sleep(0.01)
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
class GimbalSimulator(GimbalInterface):
|
|
560
|
-
"""
|
|
561
|
-
GimbalSimulator simulates the Symétrie Gimbal. The class is heavily based on the
|
|
562
|
-
ReferenceFrames in the `egse.coordinates` package.
|
|
563
|
-
|
|
564
|
-
The simulator implements the same methods as the GimbalController class which acts on the
|
|
565
|
-
real hardware controller in either simulation mode or with a real Gimbal connected.
|
|
566
|
-
|
|
567
|
-
Therefore, the GimbalSimulator can be used instead of the Gimbal class in test harnesses
|
|
568
|
-
and when the hardware is not available.
|
|
569
|
-
|
|
570
|
-
This class simulates all the movements and status of the Gimbal.
|
|
571
|
-
"""
|
|
572
|
-
|
|
573
|
-
def __init__(self):
|
|
574
|
-
self.grx_off = 0.
|
|
575
|
-
self.gry_off = 0.
|
|
576
|
-
self.mach_rx = 0.
|
|
577
|
-
self.mach_ry = 0.
|
|
578
|
-
|
|
579
|
-
# NOTE: These limits affect to user angles, NOT machine angles
|
|
580
|
-
self.min_rx = -20.51 # Tested empirically
|
|
581
|
-
self.max_rx = +20.51 # Tested empirically
|
|
582
|
-
|
|
583
|
-
self.min_ry = -20.51 # Tested empirically
|
|
584
|
-
self.max_ry = +20.51 # Tested empirically
|
|
585
|
-
|
|
586
|
-
# TODO: Look into these defaults
|
|
587
|
-
self.sr = GIMBAL_SETTINGS.DEFAULT_SPEED
|
|
588
|
-
self.sr_min = 1e-1
|
|
589
|
-
self.sr_max = 1
|
|
590
|
-
|
|
591
|
-
# Internal flags
|
|
592
|
-
self.homing_done = True # Tested empirically
|
|
593
|
-
self.control_loop = False
|
|
594
|
-
self.cs_error = False
|
|
595
|
-
self.off_limits = False
|
|
596
|
-
|
|
597
|
-
self.connected = False
|
|
598
|
-
|
|
599
|
-
def is_simulator(self):
|
|
600
|
-
return True
|
|
601
|
-
|
|
602
|
-
def connect(self):
|
|
603
|
-
self.connected = True
|
|
604
|
-
|
|
605
|
-
def reconnect(self):
|
|
606
|
-
if self.is_connected():
|
|
607
|
-
self.disconnect()
|
|
608
|
-
self.connect()
|
|
609
|
-
|
|
610
|
-
def disconnect(self):
|
|
611
|
-
# TODO:
|
|
612
|
-
# Should I keep state in this class to check if it has been disconnected?
|
|
613
|
-
#
|
|
614
|
-
# TODO:
|
|
615
|
-
# What happens when I re-connect to this Simulator? Shall it be in Homing position or
|
|
616
|
-
# do I have to keep state via a persistency mechanism?
|
|
617
|
-
self.connected = False
|
|
618
|
-
|
|
619
|
-
def is_connected(self):
|
|
620
|
-
return self.connected
|
|
621
|
-
|
|
622
|
-
def reset(self, wait=True, verbose=False):
|
|
623
|
-
# TODO:
|
|
624
|
-
# Find out what exactly a reset() should be doing. Does it bring back the Gimbal
|
|
625
|
-
# in it's original state, loosing all definitions of coordinate systems? Or does it
|
|
626
|
-
# do a clearError() and a homing()?
|
|
627
|
-
pass
|
|
628
|
-
|
|
629
|
-
def homing(self):
|
|
630
|
-
# Symétrie's Gimbal relies on absolute encoders. This causes the current Gimbal
|
|
631
|
-
# position to be unaltered, although the control loop stops.
|
|
632
|
-
self.homing_done = True
|
|
633
|
-
self.control_loop = False
|
|
634
|
-
return 0
|
|
635
|
-
|
|
636
|
-
def is_homing_done(self):
|
|
637
|
-
return self.homing_done
|
|
638
|
-
|
|
639
|
-
def stop(self):
|
|
640
|
-
pass
|
|
641
|
-
|
|
642
|
-
def clear_error(self):
|
|
643
|
-
self.cs_error = False
|
|
644
|
-
self.off_limits = False
|
|
645
|
-
|
|
646
|
-
return 0
|
|
647
|
-
|
|
648
|
-
def activate_control_loop(self):
|
|
649
|
-
self.control_loop = True
|
|
650
|
-
return self.control_loop
|
|
651
|
-
|
|
652
|
-
def deactivate_control_loop(self):
|
|
653
|
-
self.control_loop = False
|
|
654
|
-
return self.control_loop
|
|
655
|
-
|
|
656
|
-
def configure_offsets(self, grx, gry):
|
|
657
|
-
self.grx_off = grx
|
|
658
|
-
self.gry_off = gry
|
|
659
|
-
return 0
|
|
660
|
-
|
|
661
|
-
def get_offsets(self):
|
|
662
|
-
return [self.grx_off, self.gry_off]
|
|
663
|
-
|
|
664
|
-
def __compose_Q29(self):
|
|
665
|
-
q29 = 0
|
|
666
|
-
|
|
667
|
-
if not self.homing_done:
|
|
668
|
-
q29 |= 1
|
|
669
|
-
|
|
670
|
-
if self.cs_error:
|
|
671
|
-
q29 |= 2
|
|
672
|
-
|
|
673
|
-
if self.off_limits:
|
|
674
|
-
q29 |= 32
|
|
675
|
-
|
|
676
|
-
return q29
|
|
677
|
-
|
|
678
|
-
def __check_movement(self, cm, grx, gry):
|
|
679
|
-
"""
|
|
680
|
-
Ask the controller if the movement defined by the arguments is feasible.
|
|
681
|
-
|
|
682
|
-
Returns a tuple where the first element is an integer that represents the
|
|
683
|
-
bitfield encoding the errors. The second element is a dictionary with the
|
|
684
|
-
bit numbers that were (on) and the corresponding error description.
|
|
685
|
-
|
|
686
|
-
Args:
|
|
687
|
-
grx (float): rotation around the X-axis [deg]
|
|
688
|
-
gry (float): rotation around the Y-axis [deg]
|
|
689
|
-
|
|
690
|
-
"""
|
|
691
|
-
|
|
692
|
-
ret = 0
|
|
693
|
-
|
|
694
|
-
self.off_limits = False
|
|
695
|
-
|
|
696
|
-
if cm == 0:
|
|
697
|
-
target_x = grx - self.grx_off
|
|
698
|
-
target_y = gry - self.gry_off
|
|
699
|
-
elif cm == 1:
|
|
700
|
-
target_x = grx - self.grx_off
|
|
701
|
-
target_y = self.mach_ry
|
|
702
|
-
elif cm == 2:
|
|
703
|
-
target_x = self.mach_rx
|
|
704
|
-
target_y = gry - self.gry_off
|
|
705
|
-
elif cm == 10:
|
|
706
|
-
target_x = grx + self.mach_rx
|
|
707
|
-
target_y = gry + self.mach_ry
|
|
708
|
-
elif cm == 11:
|
|
709
|
-
target_x = grx + self.mach_rx
|
|
710
|
-
target_y = self.mach_ry
|
|
711
|
-
elif cm == 12:
|
|
712
|
-
target_x = self.mach_rx
|
|
713
|
-
target_y = gry + self.mach_ry
|
|
714
|
-
else:
|
|
715
|
-
target_x = math.nan
|
|
716
|
-
target_y = math.nan
|
|
717
|
-
ret = -1
|
|
718
|
-
|
|
719
|
-
# Minimal error checking. Limit checking is performed against user coordinates,
|
|
720
|
-
# and not machine coordinates.
|
|
721
|
-
user_x = target_x + self.grx_off
|
|
722
|
-
user_y = target_y + self.gry_off
|
|
723
|
-
|
|
724
|
-
if not self.homing_done:
|
|
725
|
-
ret = -2
|
|
726
|
-
elif user_x < self.min_rx or user_x > self.max_rx \
|
|
727
|
-
or user_y < self.min_ry or user_y > self.max_ry:
|
|
728
|
-
ret = -2
|
|
729
|
-
self.off_limits = True
|
|
730
|
-
|
|
731
|
-
sim_Q29 = self.__compose_Q29()
|
|
732
|
-
|
|
733
|
-
Q29 = decode_Q29(sim_Q29)
|
|
734
|
-
return ret, sim_Q29, Q29, target_x, target_y
|
|
735
|
-
|
|
736
|
-
def __move(self, cm, grx, gry):
|
|
737
|
-
rc, Q29, errors, tx, ty = self.__check_movement(cm, grx, gry)
|
|
738
|
-
|
|
739
|
-
error_code_msg = {
|
|
740
|
-
0: "Command was successful",
|
|
741
|
-
-1: "Command was ignored",
|
|
742
|
-
-2: "Command was invalid, check with POSVALID?",
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
if rc < 0:
|
|
746
|
-
msg = f"Move command returned ({rc}: {error_code_msg[rc]})."
|
|
747
|
-
|
|
748
|
-
if rc == -2:
|
|
749
|
-
msg += "\nError messages returned from POSVALID?:\n"
|
|
750
|
-
for key, value in errors.items():
|
|
751
|
-
msg += f" bit {key:<2d}: {value}\n"
|
|
752
|
-
|
|
753
|
-
logger.debug(msg)
|
|
754
|
-
else:
|
|
755
|
-
self.activate_control_loop() # Tested empirically
|
|
756
|
-
self.mach_rx = tx
|
|
757
|
-
self.mach_ry = ty
|
|
758
|
-
|
|
759
|
-
return rc
|
|
760
|
-
|
|
761
|
-
def move_absolute(self, grx, gry):
|
|
762
|
-
return self.__move(0, grx, gry)
|
|
763
|
-
|
|
764
|
-
def check_absolute_movement(self, grx, gry):
|
|
765
|
-
ret, sim_Q29, Q29, target_x, target_y = self.__check_movement(0, grx, gry)
|
|
766
|
-
return ret, Q29
|
|
767
|
-
|
|
768
|
-
def move_relative(self, grx, gry):
|
|
769
|
-
return self.__move(10, grx, gry)
|
|
770
|
-
|
|
771
|
-
def check_relative_movement(self, grx, gry):
|
|
772
|
-
ret, sim_Q29, Q29, target_x, target_y = self.__check_movement(10, grx, gry)
|
|
773
|
-
return ret, Q29
|
|
774
|
-
|
|
775
|
-
def get_user_positions(self):
|
|
776
|
-
pos = [self.mach_rx + self.grx_off, self.mach_ry + self.gry_off]
|
|
777
|
-
return pos
|
|
778
|
-
|
|
779
|
-
def get_machine_positions(self):
|
|
780
|
-
pos = [self.mach_rx, self.mach_ry]
|
|
781
|
-
return pos
|
|
782
|
-
|
|
783
|
-
def get_actuator_length(self):
|
|
784
|
-
# Tested empirically. It looks like the Gimbal holds a 1 deg/mm relationship
|
|
785
|
-
# between each axis and the corresponding actuator.
|
|
786
|
-
return self.get_machine_positions()
|
|
787
|
-
|
|
788
|
-
def get_motor_temperatures(self):
|
|
789
|
-
# Return random values, so we can see some activity in the UI during
|
|
790
|
-
# simulations.
|
|
791
|
-
return [30 + .1 * np.random.randn(), 30 + .1 * np.random.randn()]
|
|
792
|
-
|
|
793
|
-
def get_general_state(self):
|
|
794
|
-
state = 0
|
|
795
|
-
state = set_bit(state, 1) # System Initialized
|
|
796
|
-
state = set_bit(state, 2) # In Position
|
|
797
|
-
if self.homing_done:
|
|
798
|
-
state = set_bit(state, 4)
|
|
799
|
-
if self.control_loop:
|
|
800
|
-
state = set_bit(state, 3)
|
|
801
|
-
return state, decode_Q36(state)
|
|
802
|
-
|
|
803
|
-
def goto_specific_position(self, pos):
|
|
804
|
-
if pos == GimbalController.SPEC_POS_MACHINE_ZERO:
|
|
805
|
-
return self.__move(0, self.grx_off, self.gry_off)
|
|
806
|
-
elif pos == GimbalController.SPEC_POS_USER_ZERO:
|
|
807
|
-
return self.__move(0, 0, 0)
|
|
808
|
-
else:
|
|
809
|
-
return -1
|
|
810
|
-
|
|
811
|
-
def goto_zero_position(self):
|
|
812
|
-
return self.goto_specific_position(GimbalController.SPEC_POS_USER_ZERO)
|
|
813
|
-
|
|
814
|
-
def is_in_position(self):
|
|
815
|
-
return True
|
|
816
|
-
|
|
817
|
-
def jog(self, axis: int, inc: float) -> int:
|
|
818
|
-
pass
|
|
819
|
-
|
|
820
|
-
def get_debug_info(self):
|
|
821
|
-
pass
|
|
822
|
-
|
|
823
|
-
def set_speed(self, sr):
|
|
824
|
-
self.sr = sr
|
|
825
|
-
|
|
826
|
-
def get_speed(self):
|
|
827
|
-
return (self.sr, self.sr_min, self.sr_max)
|
|
828
|
-
|
|
829
|
-
def get_actuator_state(self):
|
|
830
|
-
return [({0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
|
|
831
|
-
4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
|
|
832
|
-
6: 'Brake control output'},
|
|
833
|
-
[1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), (
|
|
834
|
-
{0: 'In position', 1: 'Control loop on servo motors active', 2: 'Homing done',
|
|
835
|
-
4: 'Input "Positive limit switch"', 5: 'Input "Negative limit switch"',
|
|
836
|
-
6: 'Brake control output'},
|
|
837
|
-
[1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
|
|
838
|
-
|
|
839
|
-
def perform_maintenance(self, axis):
|
|
840
|
-
pass
|
|
841
|
-
|
|
842
|
-
def info(self):
|
|
843
|
-
|
|
844
|
-
msg = "Info about the GimbalSimulator:\n"
|
|
845
|
-
msg += "\n"
|
|
846
|
-
msg += "This Gimbal Simulator works with several reference frames:\n"
|
|
847
|
-
msg += " * The machine reference frame\n"
|
|
848
|
-
msg += " * The user reference frame\n\n"
|
|
849
|
-
msg += (
|
|
850
|
-
"Any movement commands result in a transformation of the appropriate coordinate "
|
|
851
|
-
"systems."
|
|
852
|
-
)
|
|
853
|
-
|
|
854
|
-
logger.info(msg)
|
|
855
|
-
|
|
856
|
-
return msg
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
class GimbalProxy(Proxy, GimbalInterface):
|
|
860
|
-
"""The GimbalProxy class is used to connect to the control server and send commands to the
|
|
861
|
-
Gimbal remotely."""
|
|
862
|
-
|
|
863
|
-
def __init__(
|
|
864
|
-
self,
|
|
865
|
-
protocol=CTRL_SETTINGS.PROTOCOL,
|
|
866
|
-
hostname=CTRL_SETTINGS.HOSTNAME,
|
|
867
|
-
port=CTRL_SETTINGS.COMMANDING_PORT,
|
|
868
|
-
):
|
|
869
|
-
"""
|
|
870
|
-
Args:
|
|
871
|
-
protocol: the transport protocol [default is taken from settings file]
|
|
872
|
-
hostname: location of the control server (IP address) [default is taken from settings
|
|
873
|
-
file]
|
|
874
|
-
port: TCP port on which the control server is listening for commands [default is
|
|
875
|
-
taken from settings file]
|
|
876
|
-
"""
|
|
877
|
-
super().__init__(connect_address(protocol, hostname, port))
|