microeye 2.3.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.
- microEye/__init__.py +47 -0
- microEye/_version.py +2 -0
- microEye/analysis/__init__.py +1 -0
- microEye/analysis/checklist_dialog.py +143 -0
- microEye/analysis/cmosMaps.py +228 -0
- microEye/analysis/filters/__init__.py +9 -0
- microEye/analysis/filters/base.py +21 -0
- microEye/analysis/filters/spatial.py +338 -0
- microEye/analysis/filters/temporal.py +76 -0
- microEye/analysis/fitting/__init__.py +0 -0
- microEye/analysis/fitting/fit.py +680 -0
- microEye/analysis/fitting/nena.py +375 -0
- microEye/analysis/fitting/phasor_fit.py +90 -0
- microEye/analysis/fitting/processing.py +317 -0
- microEye/analysis/fitting/psf/__init__.py +6 -0
- microEye/analysis/fitting/psf/extract.py +1129 -0
- microEye/analysis/fitting/psf/rubost_mean.py +150 -0
- microEye/analysis/fitting/psf/spline.py +167 -0
- microEye/analysis/fitting/psf/stats/__init__.py +12 -0
- microEye/analysis/fitting/psf/stats/core.py +295 -0
- microEye/analysis/fitting/psf/stats/curve_fit.py +708 -0
- microEye/analysis/fitting/psf/stats/io.py +104 -0
- microEye/analysis/fitting/psf/stats/slope_fit.py +171 -0
- microEye/analysis/fitting/psf/temp.py +147 -0
- microEye/analysis/fitting/psf/test.py +47 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +657 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +1336 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +270 -0
- microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +1 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +609 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +1396 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +1426 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +231 -0
- microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +2 -0
- microEye/analysis/fitting/pyfit3Dcspline/__init__.py +10 -0
- microEye/analysis/fitting/pyfit3Dcspline/constants.py +27 -0
- microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +903 -0
- microEye/analysis/fitting/results.py +917 -0
- microEye/analysis/fitting/results_stats.py +251 -0
- microEye/analysis/fitting/tardis.py +209 -0
- microEye/analysis/multi_viewer.py +568 -0
- microEye/analysis/processing/__init__.py +1 -0
- microEye/analysis/processing/frc.py +120 -0
- microEye/analysis/rendering/__init__.py +3 -0
- microEye/analysis/rendering/base.py +452 -0
- microEye/analysis/rendering/cloud.py +215 -0
- microEye/analysis/rendering/core.py +47 -0
- microEye/analysis/rendering/volumetric.py +198 -0
- microEye/analysis/tools/__init__.py +0 -0
- microEye/analysis/tools/kymograms.py +1079 -0
- microEye/analysis/tools/roi_selectors.py +556 -0
- microEye/analysis/utils/__init__.py +3 -0
- microEye/analysis/utils/coordinates.py +18 -0
- microEye/analysis/utils/images.py +68 -0
- microEye/analysis/utils/windows.py +19 -0
- microEye/analysis/viewer/__init__.py +3 -0
- microEye/analysis/viewer/image_options_widget.py +615 -0
- microEye/analysis/viewer/images.py +1225 -0
- microEye/analysis/viewer/layers_widget.py +415 -0
- microEye/analysis/viewer/localizations.py +1304 -0
- microEye/analysis/viewer/psf.py +1003 -0
- microEye/analysis/viewer/volume.py +456 -0
- microEye/hardware/__init__.py +3 -0
- microEye/hardware/cams/__init__.py +29 -0
- microEye/hardware/cams/camera_calibration.py +99 -0
- microEye/hardware/cams/camera_list.py +528 -0
- microEye/hardware/cams/camera_options.py +694 -0
- microEye/hardware/cams/camera_panel.py +941 -0
- microEye/hardware/cams/dummy/__init__.py +1 -0
- microEye/hardware/cams/dummy/dummy_panel.py +759 -0
- microEye/hardware/cams/jobs.py +497 -0
- microEye/hardware/cams/line_profiler.py +99 -0
- microEye/hardware/cams/linescan/IR_Cam.py +474 -0
- microEye/hardware/cams/linescan/__init__.py +1 -0
- microEye/hardware/cams/micam.py +524 -0
- microEye/hardware/cams/pco/__init__.py +58 -0
- microEye/hardware/cams/pco/enums.py +382 -0
- microEye/hardware/cams/pco/pco_cam.py +761 -0
- microEye/hardware/cams/pco/pco_panel.py +477 -0
- microEye/hardware/cams/shortcuts.py +312 -0
- microEye/hardware/cams/thorlabs/__init__.py +1 -0
- microEye/hardware/cams/thorlabs/thorlabs.py +1508 -0
- microEye/hardware/cams/thorlabs/thorlabs_panel.py +850 -0
- microEye/hardware/cams/ueye/__init__.py +1 -0
- microEye/hardware/cams/ueye/ueye_camera.py +1023 -0
- microEye/hardware/cams/ueye/ueye_panel.py +861 -0
- microEye/hardware/cams/vimba/__init__.py +1 -0
- microEye/hardware/cams/vimba/vimba_cam.py +1000 -0
- microEye/hardware/cams/vimba/vimba_panel.py +813 -0
- microEye/hardware/device.py +60 -0
- microEye/hardware/lasers/__init__.py +13 -0
- microEye/hardware/lasers/io_matchbox.py +791 -0
- microEye/hardware/lasers/io_params.py +85 -0
- microEye/hardware/lasers/io_single_laser.py +742 -0
- microEye/hardware/lasers/laser_relay.py +594 -0
- microEye/hardware/mieye/__init__.py +1 -0
- microEye/hardware/mieye/acquisition_manager.py +467 -0
- microEye/hardware/mieye/devices_manager.py +533 -0
- microEye/hardware/mieye/miEye.py +659 -0
- microEye/hardware/misc/__init__.py +0 -0
- microEye/hardware/misc/acquisition_view.py +71 -0
- microEye/hardware/misc/reglo.py +761 -0
- microEye/hardware/misc/temp.py +188 -0
- microEye/hardware/port_config.py +59 -0
- microEye/hardware/protocols/__init__.py +2 -0
- microEye/hardware/protocols/actions.py +402 -0
- microEye/hardware/protocols/actions_items.py +703 -0
- microEye/hardware/protocols/designer.py +244 -0
- microEye/hardware/protocols/scene_manager.py +191 -0
- microEye/hardware/protocols/serialization.py +97 -0
- microEye/hardware/pycromanager/__init__.py +16 -0
- microEye/hardware/pycromanager/core.py +1433 -0
- microEye/hardware/pycromanager/devices.py +461 -0
- microEye/hardware/pycromanager/enums.py +107 -0
- microEye/hardware/pycromanager/headless.py +153 -0
- microEye/hardware/pycromanager/utils.py +34 -0
- microEye/hardware/pycromanager/widgets/__init__.py +5 -0
- microEye/hardware/pycromanager/widgets/bridges.py +407 -0
- microEye/hardware/pycromanager/widgets/headless_manager.py +258 -0
- microEye/hardware/pycromanager/widgets/headless_options.py +224 -0
- microEye/hardware/pycromanager/widgets/pycro_panel.py +455 -0
- microEye/hardware/stages/__init__.py +18 -0
- microEye/hardware/stages/elliptec/__init__.py +5 -0
- microEye/hardware/stages/elliptec/baseDevice.py +314 -0
- microEye/hardware/stages/elliptec/device.py +384 -0
- microEye/hardware/stages/elliptec/deviceID.py +212 -0
- microEye/hardware/stages/elliptec/devicePort.py +379 -0
- microEye/hardware/stages/elliptec/deviceStatus.py +65 -0
- microEye/hardware/stages/elliptec/devicesView.py +706 -0
- microEye/hardware/stages/elliptec/ellDevices.py +134 -0
- microEye/hardware/stages/elliptec/messageUpdater.py +34 -0
- microEye/hardware/stages/elliptec/motorInfo.py +153 -0
- microEye/hardware/stages/elliptec/stage.py +62 -0
- microEye/hardware/stages/elliptec/test.py +139 -0
- microEye/hardware/stages/kinesis/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/__init__.py +1 -0
- microEye/hardware/stages/kinesis/kdc101/enums.py +1002 -0
- microEye/hardware/stages/kinesis/kdc101/factory.py +171 -0
- microEye/hardware/stages/kinesis/kdc101/kdc101.py +718 -0
- microEye/hardware/stages/kinesis/kinesis.py +776 -0
- microEye/hardware/stages/piezo_concept.py +607 -0
- microEye/hardware/stages/stabilizer.py +785 -0
- microEye/hardware/stages/stage.py +89 -0
- microEye/hardware/widgets/__init__.py +10 -0
- microEye/hardware/widgets/controller.py +246 -0
- microEye/hardware/widgets/devices.py +133 -0
- microEye/hardware/widgets/focusWidget.py +264 -0
- microEye/hardware/widgets/qlist_slider.py +113 -0
- microEye/hardware/widgets/scan_acquisition.py +424 -0
- microEye/icons/1024.png +0 -0
- microEye/icons/128.png +0 -0
- microEye/icons/16.png +0 -0
- microEye/icons/24.png +0 -0
- microEye/icons/256.png +0 -0
- microEye/icons/32.png +0 -0
- microEye/icons/48.png +0 -0
- microEye/icons/512.png +0 -0
- microEye/icons/64.png +0 -0
- microEye/icons/__init__.py +0 -0
- microEye/icons/close.svg +88 -0
- microEye/icons/mieye.png +0 -0
- microEye/icons/min.svg +83 -0
- microEye/icons/viewer.png +0 -0
- microEye/launcher.py +42 -0
- microEye/qt.py +181 -0
- microEye/utils/__init__.py +2 -0
- microEye/utils/enum_encoder.py +10 -0
- microEye/utils/expandable_groupbox.py +93 -0
- microEye/utils/gui_helper.py +457 -0
- microEye/utils/hid/__init__.py +8 -0
- microEye/utils/hid/controller.py +153 -0
- microEye/utils/hid/device.py +63 -0
- microEye/utils/hid/enums.py +140 -0
- microEye/utils/hid/utils.py +58 -0
- microEye/utils/labelled_slider.py +134 -0
- microEye/utils/metadata.py +599 -0
- microEye/utils/metadata_tree.py +718 -0
- microEye/utils/micro_launcher.py +245 -0
- microEye/utils/parameter_tree.py +325 -0
- microEye/utils/pyscripting.py +444 -0
- microEye/utils/retry_exec.py +35 -0
- microEye/utils/start_gui.py +112 -0
- microEye/utils/thread_worker.py +115 -0
- microEye/utils/uImage.py +1512 -0
- microeye-2.3.2.dist-info/METADATA +401 -0
- microeye-2.3.2.dist-info/RECORD +190 -0
- microeye-2.3.2.dist-info/WHEEL +5 -0
- microeye-2.3.2.dist-info/entry_points.txt +2 -0
- microeye-2.3.2.dist-info/licenses/LICENSE +674 -0
- microeye-2.3.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1002 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from enum import Enum, IntFlag, auto
|
|
4
|
+
from typing import Any, Optional, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CommandType(Enum):
|
|
8
|
+
GENERIC = auto()
|
|
9
|
+
CHANNEL = auto()
|
|
10
|
+
COMPLEX = auto()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DataType(Enum):
|
|
14
|
+
WORD = 'H' # Unsigned 16-bit integer
|
|
15
|
+
SHORT = 'h' # Signed 16-bit integer
|
|
16
|
+
DWORD = 'I' # Unsigned 32-bit integer
|
|
17
|
+
LONG = 'i' # Signed 32-bit integer
|
|
18
|
+
CHAR = 'B' # 1 byte
|
|
19
|
+
STRING = 's' # String of N characters
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class DataField:
|
|
24
|
+
name: str
|
|
25
|
+
data_type: DataType
|
|
26
|
+
length: int = 1 # For strings, specify the number of characters
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class PacketStructure:
|
|
31
|
+
data_fields: list[DataField]
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def has_data(self) -> bool:
|
|
35
|
+
return len(self.data_fields) > 0
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def has_length(self) -> bool:
|
|
39
|
+
return any(field.name == 'length' for field in self.data_fields)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class KDC101_RESPONSES(Enum):
|
|
43
|
+
def __init__(self, value, packet: Optional[PacketStructure] = None):
|
|
44
|
+
self._value_ = value
|
|
45
|
+
self.packet = packet
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
MGMSG_MOD_GET_CHANENABLESTATE = (
|
|
49
|
+
0x0212,
|
|
50
|
+
PacketStructure(
|
|
51
|
+
[
|
|
52
|
+
DataField('id', DataType.WORD),
|
|
53
|
+
DataField('channel', DataType.CHAR),
|
|
54
|
+
DataField('enable_state', DataType.CHAR),
|
|
55
|
+
DataField('destination', DataType.CHAR),
|
|
56
|
+
DataField('source', DataType.CHAR),
|
|
57
|
+
]
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
'''Response of MGMSG_MOD_REQ_CHANENABLESTATE'''
|
|
61
|
+
|
|
62
|
+
MGMSG_HW_RESPONSE = (
|
|
63
|
+
0x0080,
|
|
64
|
+
PacketStructure(
|
|
65
|
+
[
|
|
66
|
+
DataField('id', DataType.WORD),
|
|
67
|
+
DataField('code', DataType.WORD),
|
|
68
|
+
DataField('destination', DataType.CHAR),
|
|
69
|
+
DataField('source', DataType.CHAR),
|
|
70
|
+
]
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
'''Sent by the controllers to notify Thorlabs Server of some event that
|
|
74
|
+
requires user intervention, usually some fault or error condition that
|
|
75
|
+
needs to be handled before normal operation can resume.
|
|
76
|
+
|
|
77
|
+
The message transmits the fault code as a numerical value – see the
|
|
78
|
+
Return Codes listed in the Thorlabs Server helpfile for details on the
|
|
79
|
+
specific return codes.
|
|
80
|
+
'''
|
|
81
|
+
MGMSG_HW_RICHRESPONSE = (
|
|
82
|
+
0x0081,
|
|
83
|
+
PacketStructure(
|
|
84
|
+
[
|
|
85
|
+
DataField('id', DataType.WORD),
|
|
86
|
+
DataField('length', DataType.WORD),
|
|
87
|
+
DataField('destination', DataType.CHAR),
|
|
88
|
+
DataField('source', DataType.CHAR),
|
|
89
|
+
DataField('msg_id', DataType.WORD),
|
|
90
|
+
DataField('code', DataType.WORD),
|
|
91
|
+
DataField('notes', DataType.STRING, length=64),
|
|
92
|
+
]
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
'''
|
|
96
|
+
Similarly, to HW_RESPONSE, this message is sent by the controllers
|
|
97
|
+
to notify Thorlabs Server of some event that requires user
|
|
98
|
+
intervention,
|
|
99
|
+
|
|
100
|
+
usually some fault or error condition that needs to be
|
|
101
|
+
handled before normal operation can resume.
|
|
102
|
+
|
|
103
|
+
However, unlike HW_RESPONSE, this message also transmits a printable text string.
|
|
104
|
+
|
|
105
|
+
Upon receiving the message, Thorlabs Server displays both the
|
|
106
|
+
numerical value and the text information, which is useful in finding
|
|
107
|
+
the cause of the problem.
|
|
108
|
+
'''
|
|
109
|
+
|
|
110
|
+
MGMSG_HW_GET_INFO = (
|
|
111
|
+
0x0006,
|
|
112
|
+
PacketStructure(
|
|
113
|
+
[
|
|
114
|
+
DataField('id', DataType.WORD),
|
|
115
|
+
DataField('length', DataType.WORD),
|
|
116
|
+
DataField('destination', DataType.CHAR),
|
|
117
|
+
DataField('source', DataType.CHAR),
|
|
118
|
+
DataField('serial number', DataType.LONG),
|
|
119
|
+
DataField('model', DataType.STRING, length=8),
|
|
120
|
+
DataField('type', DataType.WORD),
|
|
121
|
+
DataField('minor revision number', DataType.CHAR),
|
|
122
|
+
DataField('interim revision number', DataType.CHAR),
|
|
123
|
+
DataField('major revision number', DataType.CHAR),
|
|
124
|
+
DataField('unused', DataType.CHAR),
|
|
125
|
+
DataField('hw version', DataType.WORD),
|
|
126
|
+
DataField('mod state', DataType.WORD),
|
|
127
|
+
DataField('nchs', DataType.WORD),
|
|
128
|
+
]
|
|
129
|
+
),
|
|
130
|
+
)
|
|
131
|
+
'''Response of MGMSG_HW_REQ_INFO'''
|
|
132
|
+
|
|
133
|
+
MGMSG_HUB_GET_BAYUSED = (
|
|
134
|
+
0x0066,
|
|
135
|
+
PacketStructure(
|
|
136
|
+
[
|
|
137
|
+
DataField('id', DataType.WORD),
|
|
138
|
+
DataField('bay id', DataType.CHAR),
|
|
139
|
+
DataField('unused', DataType.CHAR),
|
|
140
|
+
DataField('destination', DataType.CHAR),
|
|
141
|
+
DataField('source', DataType.CHAR),
|
|
142
|
+
]
|
|
143
|
+
),
|
|
144
|
+
)
|
|
145
|
+
'''Response of MGMSG_HUB_REQ_BAYUSED'''
|
|
146
|
+
|
|
147
|
+
MGMSG_MOT_GET_POSCOUNTER = (
|
|
148
|
+
0x0412,
|
|
149
|
+
PacketStructure(
|
|
150
|
+
[
|
|
151
|
+
DataField('id', DataType.WORD),
|
|
152
|
+
DataField('length', DataType.WORD),
|
|
153
|
+
DataField('destination', DataType.CHAR),
|
|
154
|
+
DataField('source', DataType.CHAR),
|
|
155
|
+
DataField('channel', DataType.WORD),
|
|
156
|
+
DataField('position', DataType.LONG),
|
|
157
|
+
]
|
|
158
|
+
),
|
|
159
|
+
)
|
|
160
|
+
'''Response of MGMSG_MOT_REQ_POSCOUNTER'''
|
|
161
|
+
|
|
162
|
+
MGMSG_MOT_GET_ENCCOUNTER = (
|
|
163
|
+
0x040B,
|
|
164
|
+
PacketStructure(
|
|
165
|
+
[
|
|
166
|
+
DataField('id', DataType.WORD),
|
|
167
|
+
DataField('length', DataType.WORD),
|
|
168
|
+
DataField('destination', DataType.CHAR),
|
|
169
|
+
DataField('source', DataType.CHAR),
|
|
170
|
+
DataField('channel', DataType.WORD),
|
|
171
|
+
DataField('encoder count', DataType.LONG),
|
|
172
|
+
]
|
|
173
|
+
),
|
|
174
|
+
)
|
|
175
|
+
'''Response of MGMSG_MOT_REQ_ENCCOUNTER'''
|
|
176
|
+
|
|
177
|
+
MGMSG_MOT_GET_VELPARAMS = (
|
|
178
|
+
0x0415,
|
|
179
|
+
PacketStructure(
|
|
180
|
+
[
|
|
181
|
+
DataField('id', DataType.WORD),
|
|
182
|
+
DataField('length', DataType.WORD),
|
|
183
|
+
DataField('destination', DataType.CHAR),
|
|
184
|
+
DataField('source', DataType.CHAR),
|
|
185
|
+
DataField('channel', DataType.WORD),
|
|
186
|
+
DataField('min velocity', DataType.LONG),
|
|
187
|
+
DataField('acceleration', DataType.LONG),
|
|
188
|
+
DataField('max velocity', DataType.LONG),
|
|
189
|
+
]
|
|
190
|
+
),
|
|
191
|
+
)
|
|
192
|
+
'''Response of MGMSG_MOT_REQ_VELPARAMS'''
|
|
193
|
+
|
|
194
|
+
MGMSG_MOT_GET_JOGPARAMS = (
|
|
195
|
+
0x0418,
|
|
196
|
+
PacketStructure(
|
|
197
|
+
[
|
|
198
|
+
DataField('id', DataType.WORD),
|
|
199
|
+
DataField('length', DataType.WORD),
|
|
200
|
+
DataField('destination', DataType.CHAR),
|
|
201
|
+
DataField('source', DataType.CHAR),
|
|
202
|
+
DataField('channel', DataType.WORD),
|
|
203
|
+
DataField('jog mode', DataType.WORD),
|
|
204
|
+
DataField('jog step size', DataType.LONG),
|
|
205
|
+
DataField('jog min velocity', DataType.LONG),
|
|
206
|
+
DataField('jog acceleration', DataType.LONG),
|
|
207
|
+
DataField('jog max velocity', DataType.LONG),
|
|
208
|
+
DataField('jog stop mode', DataType.WORD),
|
|
209
|
+
]
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
'''Response of MGMSG_MOT_REQ_JOGPARAMS'''
|
|
213
|
+
|
|
214
|
+
MGMSG_MOT_GET_LIMSWITCHPARAMS = (
|
|
215
|
+
0x0425,
|
|
216
|
+
PacketStructure(
|
|
217
|
+
[
|
|
218
|
+
DataField('id', DataType.WORD),
|
|
219
|
+
DataField('length', DataType.WORD),
|
|
220
|
+
DataField('destination', DataType.CHAR),
|
|
221
|
+
DataField('source', DataType.CHAR),
|
|
222
|
+
DataField('channel', DataType.WORD),
|
|
223
|
+
DataField('cw hard limit', DataType.WORD),
|
|
224
|
+
DataField('ccw hard limit', DataType.WORD),
|
|
225
|
+
DataField('cw soft limit', DataType.LONG),
|
|
226
|
+
DataField('ccw soft limit', DataType.LONG),
|
|
227
|
+
DataField('soft limit mode', DataType.WORD),
|
|
228
|
+
]
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
'''Response of MGMSG_MOT_REQ_LIMSWITCHPARAMS'''
|
|
232
|
+
|
|
233
|
+
MGMSG_MOT_GET_GENMOVEPARAMS = (
|
|
234
|
+
0x043C,
|
|
235
|
+
PacketStructure(
|
|
236
|
+
[
|
|
237
|
+
DataField('id', DataType.WORD),
|
|
238
|
+
DataField('length', DataType.WORD),
|
|
239
|
+
DataField('destination', DataType.CHAR),
|
|
240
|
+
DataField('source', DataType.CHAR),
|
|
241
|
+
DataField('channel', DataType.WORD),
|
|
242
|
+
DataField('distance', DataType.LONG),
|
|
243
|
+
]
|
|
244
|
+
),
|
|
245
|
+
)
|
|
246
|
+
'''Response of MGMSG_MOT_REQ_GENMOVEPARAMS'''
|
|
247
|
+
|
|
248
|
+
MGMSG_MOT_GET_HOMEPARAMS = (
|
|
249
|
+
0x0442,
|
|
250
|
+
PacketStructure(
|
|
251
|
+
[
|
|
252
|
+
DataField('id', DataType.WORD),
|
|
253
|
+
DataField('length', DataType.WORD),
|
|
254
|
+
DataField('destination', DataType.CHAR),
|
|
255
|
+
DataField('source', DataType.CHAR),
|
|
256
|
+
DataField('channel', DataType.WORD),
|
|
257
|
+
DataField('direction', DataType.WORD),
|
|
258
|
+
DataField('limit switch', DataType.WORD),
|
|
259
|
+
DataField('velocity', DataType.LONG),
|
|
260
|
+
DataField('zero offset', DataType.LONG),
|
|
261
|
+
]
|
|
262
|
+
),
|
|
263
|
+
)
|
|
264
|
+
'''Response of MGMSG_MOT_REQ_HOMEPARAMS'''
|
|
265
|
+
|
|
266
|
+
MGMSG_MOT_MOVE_HOMED = (
|
|
267
|
+
0x0444,
|
|
268
|
+
PacketStructure(
|
|
269
|
+
[
|
|
270
|
+
DataField('id', DataType.WORD),
|
|
271
|
+
DataField('channel', DataType.CHAR),
|
|
272
|
+
DataField('unused', DataType.CHAR),
|
|
273
|
+
DataField('destination', DataType.CHAR),
|
|
274
|
+
DataField('source', DataType.CHAR),
|
|
275
|
+
]
|
|
276
|
+
),
|
|
277
|
+
)
|
|
278
|
+
'''
|
|
279
|
+
No response on initial message, but upon completion of home
|
|
280
|
+
sequence controller sends a “homing completed” message'''
|
|
281
|
+
|
|
282
|
+
MGMSG_MOT_GET_MOVERELPARAMS = (
|
|
283
|
+
0x0447,
|
|
284
|
+
PacketStructure(
|
|
285
|
+
[
|
|
286
|
+
DataField('id', DataType.WORD),
|
|
287
|
+
DataField('length', DataType.WORD),
|
|
288
|
+
DataField('destination', DataType.CHAR),
|
|
289
|
+
DataField('source', DataType.CHAR),
|
|
290
|
+
DataField('channel', DataType.WORD),
|
|
291
|
+
DataField('distance', DataType.LONG),
|
|
292
|
+
]
|
|
293
|
+
),
|
|
294
|
+
)
|
|
295
|
+
'''Response of MGMSG_MOT_REQ_MOVERELPARAMS'''
|
|
296
|
+
|
|
297
|
+
MGMSG_MOT_GET_MOVEABSPARAMS = (
|
|
298
|
+
0x0452,
|
|
299
|
+
PacketStructure(
|
|
300
|
+
[
|
|
301
|
+
DataField('id', DataType.WORD),
|
|
302
|
+
DataField('length', DataType.WORD),
|
|
303
|
+
DataField('destination', DataType.CHAR),
|
|
304
|
+
DataField('source', DataType.CHAR),
|
|
305
|
+
DataField('channel', DataType.WORD),
|
|
306
|
+
DataField('position', DataType.LONG),
|
|
307
|
+
]
|
|
308
|
+
),
|
|
309
|
+
)
|
|
310
|
+
'''Response of MGMSG_MOT_REQ_MOVEABSPARAMS'''
|
|
311
|
+
|
|
312
|
+
MGMSG_MOT_MOVE_COMPLETED = (
|
|
313
|
+
0x0464,
|
|
314
|
+
PacketStructure(
|
|
315
|
+
[
|
|
316
|
+
DataField('id', DataType.WORD),
|
|
317
|
+
DataField('channel', DataType.CHAR),
|
|
318
|
+
DataField('unused', DataType.CHAR),
|
|
319
|
+
DataField('destination', DataType.CHAR),
|
|
320
|
+
DataField('source', DataType.CHAR),
|
|
321
|
+
# MOT DC STATUS
|
|
322
|
+
DataField('channel', DataType.WORD),
|
|
323
|
+
DataField('position', DataType.LONG),
|
|
324
|
+
DataField('velocity', DataType.WORD),
|
|
325
|
+
DataField('motor current', DataType.WORD),
|
|
326
|
+
DataField('status bits', DataType.DWORD),
|
|
327
|
+
]
|
|
328
|
+
),
|
|
329
|
+
)
|
|
330
|
+
'''
|
|
331
|
+
No response on initial message, but upon completion of the relative
|
|
332
|
+
or absolute move sequence, the controller sends a “move
|
|
333
|
+
completed” message.
|
|
334
|
+
'''
|
|
335
|
+
|
|
336
|
+
MGMSG_MOT_MOVE_STOPPED = (
|
|
337
|
+
0x0466,
|
|
338
|
+
PacketStructure(
|
|
339
|
+
[
|
|
340
|
+
DataField('id', DataType.WORD),
|
|
341
|
+
DataField('length', DataType.WORD),
|
|
342
|
+
DataField('destination', DataType.CHAR),
|
|
343
|
+
DataField('source', DataType.CHAR),
|
|
344
|
+
# MOT DC STATUS
|
|
345
|
+
DataField('channel', DataType.WORD),
|
|
346
|
+
DataField('position', DataType.LONG),
|
|
347
|
+
DataField('velocity', DataType.WORD),
|
|
348
|
+
DataField('motor current', DataType.WORD),
|
|
349
|
+
DataField('status bits', DataType.DWORD),
|
|
350
|
+
]
|
|
351
|
+
),
|
|
352
|
+
)
|
|
353
|
+
'''
|
|
354
|
+
No response on initial message, but upon completion of the stop
|
|
355
|
+
move, the controller sends a “move stopped” message.
|
|
356
|
+
'''
|
|
357
|
+
|
|
358
|
+
MGMSG_MOT_GET_DCSTATUSUPDATE = (
|
|
359
|
+
0x0491,
|
|
360
|
+
PacketStructure(
|
|
361
|
+
[
|
|
362
|
+
DataField('id', DataType.WORD),
|
|
363
|
+
DataField('length', DataType.WORD),
|
|
364
|
+
DataField('destination', DataType.CHAR),
|
|
365
|
+
DataField('source', DataType.CHAR),
|
|
366
|
+
# MOT DC STATUS
|
|
367
|
+
DataField('channel', DataType.WORD),
|
|
368
|
+
DataField('position', DataType.LONG),
|
|
369
|
+
DataField('velocity', DataType.WORD),
|
|
370
|
+
DataField('motor current', DataType.WORD),
|
|
371
|
+
DataField('status bits', DataType.DWORD),
|
|
372
|
+
]
|
|
373
|
+
),
|
|
374
|
+
)
|
|
375
|
+
'''Response of MGMSG_MOT_REQ_DCSTATUSUPDATE'''
|
|
376
|
+
|
|
377
|
+
# MGMSG_MOT_ACK_DCSTATUSUPDATE = 0x0492
|
|
378
|
+
'''Acknowledgement of MGMSG_MOT_REQ_DCSTATUSUPDATE
|
|
379
|
+
|
|
380
|
+
Only Applicable If Using USB COMMS. Does not apply to RS-232 COMMS'''
|
|
381
|
+
|
|
382
|
+
MGMSG_MOT_GET_STATUSBITS = (
|
|
383
|
+
0x042A,
|
|
384
|
+
PacketStructure(
|
|
385
|
+
[
|
|
386
|
+
DataField('id', DataType.WORD),
|
|
387
|
+
DataField('length', DataType.WORD),
|
|
388
|
+
DataField('destination', DataType.CHAR),
|
|
389
|
+
DataField('source', DataType.CHAR),
|
|
390
|
+
DataField('channel', DataType.WORD),
|
|
391
|
+
DataField('status bits', DataType.DWORD),
|
|
392
|
+
]
|
|
393
|
+
),
|
|
394
|
+
)
|
|
395
|
+
'''Response of MGMSG_MOT_REQ_STATUSBITS'''
|
|
396
|
+
|
|
397
|
+
@classmethod
|
|
398
|
+
def get(cls, response: Union[int, list]):
|
|
399
|
+
'''Get the response enum for a given response code.'''
|
|
400
|
+
try:
|
|
401
|
+
if isinstance(response, list):
|
|
402
|
+
if len(response) < 2:
|
|
403
|
+
raise ValueError('Not enough bytes to get command.')
|
|
404
|
+
|
|
405
|
+
response = (response[1] << 8) | response[0]
|
|
406
|
+
|
|
407
|
+
if not isinstance(response, int):
|
|
408
|
+
raise ValueError(
|
|
409
|
+
'Command must be an integer or list of integers/bytes.'
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
# Iterate through enum members to find the one with the matching value
|
|
413
|
+
for member in cls:
|
|
414
|
+
if member.value == response:
|
|
415
|
+
return member
|
|
416
|
+
except ValueError:
|
|
417
|
+
return None
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
class KDC101_CMDS(Enum):
|
|
421
|
+
def __init__(
|
|
422
|
+
self,
|
|
423
|
+
value,
|
|
424
|
+
cmd_type: CommandType,
|
|
425
|
+
packet: Optional[PacketStructure] = None,
|
|
426
|
+
response: Optional[KDC101_RESPONSES] = None,
|
|
427
|
+
):
|
|
428
|
+
self._value_ = value
|
|
429
|
+
self.cmd_type = cmd_type
|
|
430
|
+
self.packet = packet
|
|
431
|
+
self.response = response
|
|
432
|
+
|
|
433
|
+
MGMSG_MOD_IDENTIFY = (0x0223, CommandType.CHANNEL)
|
|
434
|
+
'''Instruct hardware unit to identify itself (by flashing its front panel
|
|
435
|
+
LEDs).'''
|
|
436
|
+
|
|
437
|
+
MGMSG_MOD_SET_CHANENABLESTATE = (0x0210, CommandType.CHANNEL)
|
|
438
|
+
'''Sent to enable or disable the specified drive channel.'''
|
|
439
|
+
MGMSG_MOD_REQ_CHANENABLESTATE = (
|
|
440
|
+
0x0211,
|
|
441
|
+
CommandType.CHANNEL,
|
|
442
|
+
None,
|
|
443
|
+
KDC101_RESPONSES.MGMSG_MOD_GET_CHANENABLESTATE,
|
|
444
|
+
)
|
|
445
|
+
'''Sent to request the enable state of the specified drive channel.'''
|
|
446
|
+
|
|
447
|
+
MGMSG_HW_DISCONNECT = (0x0002, CommandType.GENERIC)
|
|
448
|
+
'''Sent by the hardware unit or host to disconnect from the
|
|
449
|
+
Ethernet/USB bus.'''
|
|
450
|
+
|
|
451
|
+
MGMSG_HW_START_UPDATEMSGS = (0x0011, CommandType.GENERIC)
|
|
452
|
+
'''Sent to start automatic status updates from the embedded controller.'''
|
|
453
|
+
MGMSG_HW_STOP_UPDATEMSGS = (0x0012, CommandType.GENERIC)
|
|
454
|
+
'''
|
|
455
|
+
Sent to stop automatic status updates from the controller – usually
|
|
456
|
+
called by a client application when it is shutting down, to instruct
|
|
457
|
+
the controller to turn off status updates to prevent USB buffer
|
|
458
|
+
overflows on the PC.
|
|
459
|
+
'''
|
|
460
|
+
|
|
461
|
+
MGMSG_HW_REQ_INFO = (
|
|
462
|
+
0x0005,
|
|
463
|
+
CommandType.GENERIC,
|
|
464
|
+
None,
|
|
465
|
+
KDC101_RESPONSES.MGMSG_HW_GET_INFO,
|
|
466
|
+
)
|
|
467
|
+
'''Sent to request hardware information from the controller.'''
|
|
468
|
+
|
|
469
|
+
MGMSG_HUB_REQ_BAYUSED = (
|
|
470
|
+
0x0065,
|
|
471
|
+
CommandType.GENERIC,
|
|
472
|
+
None,
|
|
473
|
+
KDC101_RESPONSES.MGMSG_HUB_GET_BAYUSED,
|
|
474
|
+
)
|
|
475
|
+
'''Sent to determine to which bay a specific unit is fitted.'''
|
|
476
|
+
|
|
477
|
+
MGMSG_MOT_REQ_POSCOUNTER = (
|
|
478
|
+
0x0411,
|
|
479
|
+
CommandType.CHANNEL,
|
|
480
|
+
None,
|
|
481
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_POSCOUNTER,
|
|
482
|
+
)
|
|
483
|
+
'''Used to request the ‘live’ position count in the controller.'''
|
|
484
|
+
|
|
485
|
+
MGMSG_MOT_REQ_ENCCOUNTER = (
|
|
486
|
+
0x040A,
|
|
487
|
+
CommandType.CHANNEL,
|
|
488
|
+
None,
|
|
489
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_ENCCOUNTER,
|
|
490
|
+
)
|
|
491
|
+
'''
|
|
492
|
+
Used to set the encoder count in the controller and is
|
|
493
|
+
only applicable to stages and actuators fitted with an encoder.
|
|
494
|
+
'''
|
|
495
|
+
|
|
496
|
+
MGMSG_MOT_SET_VELPARAMS = (
|
|
497
|
+
0x0413,
|
|
498
|
+
CommandType.COMPLEX,
|
|
499
|
+
PacketStructure(
|
|
500
|
+
[
|
|
501
|
+
DataField('min_velocity', DataType.LONG),
|
|
502
|
+
DataField('acceleration', DataType.LONG),
|
|
503
|
+
DataField('max_velocity', DataType.LONG),
|
|
504
|
+
]
|
|
505
|
+
),
|
|
506
|
+
)
|
|
507
|
+
'''
|
|
508
|
+
Used to set the trapezoidal velocity parameters for the specified
|
|
509
|
+
motor channel.
|
|
510
|
+
|
|
511
|
+
For DC servo controllers, the velocity is set in
|
|
512
|
+
encoder counts/sec and acceleration is set in encoder
|
|
513
|
+
counts/sec/sec.
|
|
514
|
+
|
|
515
|
+
For stepper motor controllers the velocity is set in microsteps/sec
|
|
516
|
+
and acceleration is set in microsteps/sec/sec.'''
|
|
517
|
+
MGMSG_MOT_REQ_VELPARAMS = (
|
|
518
|
+
0x0414,
|
|
519
|
+
CommandType.CHANNEL,
|
|
520
|
+
None,
|
|
521
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_VELPARAMS,
|
|
522
|
+
)
|
|
523
|
+
'''
|
|
524
|
+
Used to request the trapezoidal velocity parameters for the specified motor channel.
|
|
525
|
+
'''
|
|
526
|
+
|
|
527
|
+
MGMSG_MOT_SET_JOGPARAMS = (
|
|
528
|
+
0x0416,
|
|
529
|
+
CommandType.COMPLEX,
|
|
530
|
+
PacketStructure(
|
|
531
|
+
[
|
|
532
|
+
DataField('jog_mode', DataType.WORD),
|
|
533
|
+
DataField('jog_step_size', DataType.LONG),
|
|
534
|
+
DataField('jog_min_velocity', DataType.LONG),
|
|
535
|
+
DataField('jog_acceleration', DataType.LONG),
|
|
536
|
+
DataField('jog_max_velocity', DataType.LONG),
|
|
537
|
+
DataField('jog_stop_mode', DataType.WORD),
|
|
538
|
+
]
|
|
539
|
+
),
|
|
540
|
+
)
|
|
541
|
+
'''
|
|
542
|
+
Used to set the velocity jog parameters for the specified motor
|
|
543
|
+
channel.
|
|
544
|
+
|
|
545
|
+
For DC servo controllers, values set in encoder counts.
|
|
546
|
+
|
|
547
|
+
For stepper motor controllers the values is set in microsteps.'''
|
|
548
|
+
MGMSG_MOT_REQ_JOGPARAMS = (
|
|
549
|
+
0x0417,
|
|
550
|
+
CommandType.CHANNEL,
|
|
551
|
+
None,
|
|
552
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_JOGPARAMS,
|
|
553
|
+
)
|
|
554
|
+
'''Used to request the velocity jog parameters for the specified motor channel.'''
|
|
555
|
+
|
|
556
|
+
MGMSG_MOT_SET_LIMSWITCHPARAMS = (
|
|
557
|
+
0x0423,
|
|
558
|
+
CommandType.COMPLEX,
|
|
559
|
+
PacketStructure(
|
|
560
|
+
[
|
|
561
|
+
DataField('cw_hard_limit', DataType.WORD),
|
|
562
|
+
DataField('ccw_hard_limit', DataType.WORD),
|
|
563
|
+
DataField('cw_soft_limit', DataType.LONG),
|
|
564
|
+
DataField('ccw_soft_limit', DataType.LONG),
|
|
565
|
+
DataField('soft_limit_mode', DataType.WORD),
|
|
566
|
+
]
|
|
567
|
+
),
|
|
568
|
+
)
|
|
569
|
+
'''
|
|
570
|
+
Used to set the limit switch parameters for the specified motor channel.
|
|
571
|
+
'''
|
|
572
|
+
MGMSG_MOT_REQ_LIMSWITCHPARAMS = (
|
|
573
|
+
0x0424,
|
|
574
|
+
CommandType.CHANNEL,
|
|
575
|
+
None,
|
|
576
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_LIMSWITCHPARAMS,
|
|
577
|
+
)
|
|
578
|
+
'''Used to request the limit switch parameters for the specified motor channel.'''
|
|
579
|
+
|
|
580
|
+
MGMSG_MOT_SET_GENMOVEPARAMS = (
|
|
581
|
+
0x043A,
|
|
582
|
+
CommandType.COMPLEX,
|
|
583
|
+
PacketStructure([DataField('distance', DataType.LONG)]),
|
|
584
|
+
)
|
|
585
|
+
'''
|
|
586
|
+
Used to set the general move parameters for the specified motor channel.
|
|
587
|
+
|
|
588
|
+
Currently this refers specifically to the backlash settings. '''
|
|
589
|
+
MGMSG_MOT_REQ_GENMOVEPARAMS = (
|
|
590
|
+
0x043B,
|
|
591
|
+
CommandType.CHANNEL,
|
|
592
|
+
None,
|
|
593
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_GENMOVEPARAMS,
|
|
594
|
+
)
|
|
595
|
+
'''Used to request the general move parameters for the specified motor channel.'''
|
|
596
|
+
|
|
597
|
+
MGMSG_MOT_SET_HOMEPARAMS = (
|
|
598
|
+
0x0440,
|
|
599
|
+
CommandType.COMPLEX,
|
|
600
|
+
PacketStructure(
|
|
601
|
+
[
|
|
602
|
+
DataField('direction', DataType.WORD),
|
|
603
|
+
DataField('lim_switch', DataType.WORD),
|
|
604
|
+
DataField('velocity', DataType.LONG),
|
|
605
|
+
DataField('zero_offset', DataType.LONG),
|
|
606
|
+
]
|
|
607
|
+
),
|
|
608
|
+
)
|
|
609
|
+
'''
|
|
610
|
+
Used to set the home parameters for the specified motor channel.
|
|
611
|
+
|
|
612
|
+
These parameters are stage specific and for the MLS203 stage
|
|
613
|
+
implementation the only parameter that can be changed is the
|
|
614
|
+
homing velocity.'''
|
|
615
|
+
|
|
616
|
+
MGMSG_MOT_REQ_HOMEPARAMS = (
|
|
617
|
+
0x0441,
|
|
618
|
+
CommandType.CHANNEL,
|
|
619
|
+
None,
|
|
620
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_HOMEPARAMS,
|
|
621
|
+
)
|
|
622
|
+
'''
|
|
623
|
+
Used to request the home parameters for the specified motor channel.'''
|
|
624
|
+
|
|
625
|
+
MGMSG_MOT_SET_MOVERELPARAMS = (
|
|
626
|
+
0x0445,
|
|
627
|
+
CommandType.COMPLEX,
|
|
628
|
+
PacketStructure([DataField('distance', DataType.LONG)]),
|
|
629
|
+
)
|
|
630
|
+
'''
|
|
631
|
+
Used to set the relative move parameters for the specified motor channel.
|
|
632
|
+
|
|
633
|
+
The only significant parameter currently is the relative move distance itself.
|
|
634
|
+
|
|
635
|
+
This gets stored by the controller and is used the next time a relative move
|
|
636
|
+
is initiated.'''
|
|
637
|
+
MGMSG_MOT_REQ_MOVERELPARAMS = (
|
|
638
|
+
0x0446,
|
|
639
|
+
CommandType.CHANNEL,
|
|
640
|
+
None,
|
|
641
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_MOVERELPARAMS,
|
|
642
|
+
)
|
|
643
|
+
'''Used to request the relative move parameters for the specified motor channel.'''
|
|
644
|
+
|
|
645
|
+
MGMSG_MOT_SET_MOVEABSPARAMS = (
|
|
646
|
+
0x0450,
|
|
647
|
+
CommandType.COMPLEX,
|
|
648
|
+
PacketStructure([DataField('position', DataType.LONG)]),
|
|
649
|
+
)
|
|
650
|
+
'''
|
|
651
|
+
Used to set the absolute move parameters for the specified motor channel.
|
|
652
|
+
|
|
653
|
+
The only significant parameter currently is the absolute
|
|
654
|
+
move position itself.
|
|
655
|
+
|
|
656
|
+
This gets stored by the controller and is used
|
|
657
|
+
the next time an absolute move is initiated.
|
|
658
|
+
'''
|
|
659
|
+
MGMSG_MOT_REQ_MOVEABSPARAMS = (
|
|
660
|
+
0x0451,
|
|
661
|
+
CommandType.CHANNEL,
|
|
662
|
+
None,
|
|
663
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_MOVEABSPARAMS,
|
|
664
|
+
)
|
|
665
|
+
'''Used to request the absolute move parameters for the specified motor channel.'''
|
|
666
|
+
|
|
667
|
+
MGMSG_MOT_MOVE_HOME = (
|
|
668
|
+
0x0443,
|
|
669
|
+
CommandType.CHANNEL,
|
|
670
|
+
None,
|
|
671
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_HOMED,
|
|
672
|
+
)
|
|
673
|
+
'''Sent to start a home move sequence on the specified motor channel.'''
|
|
674
|
+
|
|
675
|
+
MGMSG_MOT_MOVE_RELATIVE = (
|
|
676
|
+
0x0448,
|
|
677
|
+
CommandType.COMPLEX,
|
|
678
|
+
PacketStructure([DataField('distance', DataType.LONG)]),
|
|
679
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_COMPLETED,
|
|
680
|
+
)
|
|
681
|
+
'''
|
|
682
|
+
This command can be used to start a relative move on the specified
|
|
683
|
+
motor channel (using the relative move distance parameter above).
|
|
684
|
+
|
|
685
|
+
There are two versions of this command: a shorter (6-byte header
|
|
686
|
+
only) version and a longer (6 byte header plus 6 data bytes) version.
|
|
687
|
+
|
|
688
|
+
When the first one is used, the relative distance parameter used for
|
|
689
|
+
the move will be the parameter sent previously by a
|
|
690
|
+
MGMSG_MOT_SET_MOVERELPARAMS command.
|
|
691
|
+
|
|
692
|
+
If the longer version of the command is used, the relative distance
|
|
693
|
+
is encoded in the data packet that follows the header.
|
|
694
|
+
'''
|
|
695
|
+
|
|
696
|
+
MGMSG_MOT_MOVE_ABSOLUTE = (
|
|
697
|
+
0x0453,
|
|
698
|
+
CommandType.COMPLEX,
|
|
699
|
+
PacketStructure([DataField('position', DataType.LONG)]),
|
|
700
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_COMPLETED,
|
|
701
|
+
)
|
|
702
|
+
'''
|
|
703
|
+
Used to start an absolute move on the specified motor channel
|
|
704
|
+
(using the absolute move position parameter above).
|
|
705
|
+
|
|
706
|
+
As previously described in the “MOVE RELATIVE” command, there are two
|
|
707
|
+
versions of this command: a shorter (6-byte header only) version
|
|
708
|
+
and a longer (6 byte header plus 6 data bytes) version.
|
|
709
|
+
|
|
710
|
+
When the first one is used, the absolute move position parameter used for the
|
|
711
|
+
move will be the parameter sent previously by a MGMSG_MOT_SET_MOVEABSPARAMS command.
|
|
712
|
+
|
|
713
|
+
If the longer version of the command is used, the absolute position is encoded in
|
|
714
|
+
the data packet that follows the header.
|
|
715
|
+
|
|
716
|
+
Upon completion of the absolute move the controller sends a Move Completed message
|
|
717
|
+
as previously described.
|
|
718
|
+
'''
|
|
719
|
+
|
|
720
|
+
MGMSG_MOT_MOVE_JOG = (
|
|
721
|
+
0x046A,
|
|
722
|
+
CommandType.CHANNEL,
|
|
723
|
+
None,
|
|
724
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_COMPLETED,
|
|
725
|
+
)
|
|
726
|
+
'''Sent to start a jog move on the specified motor channel.
|
|
727
|
+
|
|
728
|
+
Upon completion of the jog move the controller sends a Move Completed message as
|
|
729
|
+
previously described.
|
|
730
|
+
|
|
731
|
+
**Note:**
|
|
732
|
+
The direction of the jog move is device dependent, i.e., on some devices jog forward
|
|
733
|
+
may be towards the home position while on other devices it could be the opposite.'''
|
|
734
|
+
|
|
735
|
+
MGMSG_MOT_MOVE_VELOCITY = (
|
|
736
|
+
0x0457,
|
|
737
|
+
CommandType.CHANNEL,
|
|
738
|
+
None,
|
|
739
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_COMPLETED,
|
|
740
|
+
)
|
|
741
|
+
'''
|
|
742
|
+
This command can be used to start a move on the specified motor
|
|
743
|
+
channel.
|
|
744
|
+
|
|
745
|
+
When this method is called, the motor will move continuously in the
|
|
746
|
+
specified direction, using the velocity parameters set in the
|
|
747
|
+
MGMSG_MOT_SET_VELPARAMS command until either a stop
|
|
748
|
+
command (either StopImmediate or StopProfiled) is called, or a limit
|
|
749
|
+
switch is reached.
|
|
750
|
+
'''
|
|
751
|
+
|
|
752
|
+
MGMSG_MOT_MOVE_STOP = (
|
|
753
|
+
0x0465,
|
|
754
|
+
CommandType.CHANNEL,
|
|
755
|
+
None,
|
|
756
|
+
KDC101_RESPONSES.MGMSG_MOT_MOVE_STOPPED,
|
|
757
|
+
)
|
|
758
|
+
'''
|
|
759
|
+
Sent to stop any type of motor move (relative, absolute, homing or move at velocity)
|
|
760
|
+
on the specified motor channel.
|
|
761
|
+
'''
|
|
762
|
+
|
|
763
|
+
MGMSG_MOT_REQ_DCSTATUSUPDATE = (
|
|
764
|
+
0x0490,
|
|
765
|
+
CommandType.CHANNEL,
|
|
766
|
+
None,
|
|
767
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_DCSTATUSUPDATE,
|
|
768
|
+
)
|
|
769
|
+
'''
|
|
770
|
+
Used to request a status update for the specified motor channel.
|
|
771
|
+
|
|
772
|
+
This request can be used instead of enabling regular updates as
|
|
773
|
+
described above.'''
|
|
774
|
+
|
|
775
|
+
MGMSG_MOT_REQ_STATUSBITS = (
|
|
776
|
+
0x0429,
|
|
777
|
+
CommandType.CHANNEL,
|
|
778
|
+
None,
|
|
779
|
+
KDC101_RESPONSES.MGMSG_MOT_GET_STATUSBITS,
|
|
780
|
+
)
|
|
781
|
+
'''
|
|
782
|
+
Used to request a “cut down” version of the status update message,
|
|
783
|
+
only containing the status bits, without data about position and
|
|
784
|
+
velocity.
|
|
785
|
+
'''
|
|
786
|
+
|
|
787
|
+
MGMSG_MOT_SUSPEND_ENDOFMOVEMSGS = (0x046B, CommandType.GENERIC)
|
|
788
|
+
'''
|
|
789
|
+
Sent to disable all unsolicited end of move messages and error
|
|
790
|
+
messages returned by the controller, i.e.
|
|
791
|
+
|
|
792
|
+
- MGMSG_MOT_MOVE_STOPPED
|
|
793
|
+
- MGMSG_MOT_MOVE_COMPLETED
|
|
794
|
+
- MGMSG_MOT_MOVE_HOMED
|
|
795
|
+
'''
|
|
796
|
+
|
|
797
|
+
MGMSG_MOT_RESUME_ENDOFMOVEMSGS = (0x046C, CommandType.GENERIC)
|
|
798
|
+
'''
|
|
799
|
+
Sent to resume all unsolicited end of move messages and error
|
|
800
|
+
messages returned by the controller, i.e.
|
|
801
|
+
|
|
802
|
+
- MGMSG_MOT_MOVE_STOPPED
|
|
803
|
+
- MGMSG_MOT_MOVE_COMPLETED
|
|
804
|
+
- MGMSG_MOT_MOVE_HOMED
|
|
805
|
+
|
|
806
|
+
The command also disables the error messages that the controller
|
|
807
|
+
sends when an error conditions is detected:
|
|
808
|
+
|
|
809
|
+
- MGMSG_HW_RESPONSE
|
|
810
|
+
- MGMSG_HW_RICHRESPONSE
|
|
811
|
+
|
|
812
|
+
This is the default state when the controller is powered up.'''
|
|
813
|
+
|
|
814
|
+
@classmethod
|
|
815
|
+
def get(cls, cmd: Union[int, list]):
|
|
816
|
+
'''Get the command enum for a given command code.'''
|
|
817
|
+
try:
|
|
818
|
+
if isinstance(cmd, list):
|
|
819
|
+
if len(cmd) < 2:
|
|
820
|
+
raise ValueError('Not enough bytes to get command.')
|
|
821
|
+
|
|
822
|
+
cmd = (cmd[1] << 8) | cmd[0]
|
|
823
|
+
|
|
824
|
+
if not isinstance(cmd, int):
|
|
825
|
+
raise ValueError(
|
|
826
|
+
'Command must be an integer or list of integers/bytes.'
|
|
827
|
+
)
|
|
828
|
+
|
|
829
|
+
# Iterate through enum members to find the one with the matching value
|
|
830
|
+
for member in cls:
|
|
831
|
+
if member.value == cmd:
|
|
832
|
+
return member
|
|
833
|
+
except ValueError:
|
|
834
|
+
return None
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
class Channels(Enum):
|
|
838
|
+
NA = 0x00
|
|
839
|
+
CHAN1 = 0x01
|
|
840
|
+
CHAN2 = 0x02
|
|
841
|
+
CHAN3 = 0x04
|
|
842
|
+
CHAN4 = 0x08
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
class ChannelEnableState(Enum):
|
|
846
|
+
ENABLE = 0x01
|
|
847
|
+
DISABLE = 0x02
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
class BayStates(Enum):
|
|
851
|
+
BAY_OCCUPIED = 0x01
|
|
852
|
+
BAY_EMPTY = 0x02
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
class HubBayIdents(Enum):
|
|
856
|
+
STANDALONE = 0x01 # T-Cube being standalone, i.e., off the hub
|
|
857
|
+
UNKNOWN = 0x00 # T-Cube on hub, but bay unknown
|
|
858
|
+
BAY_1 = 0x01 # Bay 1
|
|
859
|
+
BAY_2 = 0x02 # Bay 2
|
|
860
|
+
BAY_3 = 0x03 # Bay 3
|
|
861
|
+
BAY_4 = 0x04 # Bay 4
|
|
862
|
+
BAY_5 = 0x05 # Bay 5
|
|
863
|
+
BAY_6 = 0x06 # Bay 6
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
class JogDirection(Enum):
|
|
867
|
+
FORWARD = 0x01 # Jog forward
|
|
868
|
+
REVERSE = 0x02 # Jog in the reverse direction
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
class JogMode(Enum):
|
|
872
|
+
CONTINUOUS = 0x01 # Continuous jogging
|
|
873
|
+
SINGLE_STEP = 0x02 # Single step jogging
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
class StopMode(Enum):
|
|
877
|
+
IMMEDIATE = 0x01 # Stop immediately (abrupt)
|
|
878
|
+
PROFILED = 0x02 # Stop in a controller (profiled) manner
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
class MotorStatusBits(Enum):
|
|
882
|
+
P_MOT_SB_CWHARDLIMIT = 0x00000001
|
|
883
|
+
'''
|
|
884
|
+
Clockwise hardware limit switch.
|
|
885
|
+
|
|
886
|
+
On linear stages, this corresponds to the forward limit switch.'''
|
|
887
|
+
|
|
888
|
+
P_MOT_SB_CCWHARDLIMIT = 0x00000002
|
|
889
|
+
'''
|
|
890
|
+
Counter-clockwise hardware limit switch.
|
|
891
|
+
|
|
892
|
+
On linear stages, this corresponds to the reverse limit switch.'''
|
|
893
|
+
|
|
894
|
+
P_MOT_SB_CWSOFTLIMIT = 0x00000004
|
|
895
|
+
'''
|
|
896
|
+
Clockwise software limit switch.
|
|
897
|
+
|
|
898
|
+
Restricts motion to a narrower range than the hardware limit switch.'''
|
|
899
|
+
|
|
900
|
+
P_MOT_SB_CCWSOFTLIMIT = 0x00000008
|
|
901
|
+
'''
|
|
902
|
+
Counter-clockwise software limit switch.
|
|
903
|
+
|
|
904
|
+
Restricts motion to a narrower range than the hardware limit switch.'''
|
|
905
|
+
|
|
906
|
+
P_MOT_SB_INMOTIONCW = 0x00000010
|
|
907
|
+
'''Indicates that the motor is in motion, moving clockwise.'''
|
|
908
|
+
|
|
909
|
+
P_MOT_SB_INMOTIONCCW = 0x00000020
|
|
910
|
+
'''Indicates that the motor is in motion, moving counter-clockwise.'''
|
|
911
|
+
|
|
912
|
+
P_MOT_SB_JOGGINGCW = 0x00000040
|
|
913
|
+
'''Indicates that the motor is jogging, moving clockwise.'''
|
|
914
|
+
|
|
915
|
+
P_MOT_SB_JOGGINGCCW = 0x00000080
|
|
916
|
+
'''Indicates that the motor is jogging, moving counter-clockwise.'''
|
|
917
|
+
|
|
918
|
+
P_MOT_SB_CONNECTED = 0x00000100
|
|
919
|
+
'''Indicates that the motor has been recognized by the controller.'''
|
|
920
|
+
|
|
921
|
+
P_MOT_SB_HOMING = 0x00000200
|
|
922
|
+
'''Indicates that the motor is performing a homing move.'''
|
|
923
|
+
|
|
924
|
+
P_MOT_SB_HOMED = 0x00000400
|
|
925
|
+
'''Indicates that the motor has completed the homing move,
|
|
926
|
+
and the absolute position is known.'''
|
|
927
|
+
|
|
928
|
+
P_MOT_SB_POSITIONERROR = 0x00004000
|
|
929
|
+
'''
|
|
930
|
+
Indicates that the actual position is outside the margin specified around the
|
|
931
|
+
trajectory position.
|
|
932
|
+
|
|
933
|
+
(In simple terms the motor is not where it should be.)
|
|
934
|
+
|
|
935
|
+
This can occur momentarily during fast acceleration
|
|
936
|
+
(the motor lags behind the trajectory) or when the motor
|
|
937
|
+
is jammed, or the move is obstructed.
|
|
938
|
+
|
|
939
|
+
Typically the condition can trigger the controller to disable
|
|
940
|
+
the motor in order to prevent damage, which in turn will clear the error.
|
|
941
|
+
'''
|
|
942
|
+
P_MOT_SB_DIGIP1 = 0x00100000
|
|
943
|
+
P_MOT_SB_DIGIP2 = 0x00200000
|
|
944
|
+
|
|
945
|
+
P_MOT_SB_ERROR = 0x40000000
|
|
946
|
+
'''
|
|
947
|
+
Indicates an error condition, either listed above or arising as a result of another
|
|
948
|
+
abnormal condition.'''
|
|
949
|
+
P_MOT_SB_ENABLED = 0x80000000
|
|
950
|
+
'''
|
|
951
|
+
Indicates that the motor output is enabled and the controller is in charge of
|
|
952
|
+
maintaining the required position.
|
|
953
|
+
|
|
954
|
+
When the output is disabled, the motor is not controlled by the electronics
|
|
955
|
+
and can be moved manually, as much as the mechanical construction (such as
|
|
956
|
+
any leadscrew and gearbox fitted) allows.
|
|
957
|
+
|
|
958
|
+
This is not full list of all the bits but the remaining bits reflect information
|
|
959
|
+
about the state of the hardware that in most cases does not affect motion.
|
|
960
|
+
'''
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
class LimitSwitchOperation(IntFlag):
|
|
964
|
+
'''Clockwise Limit switch operation flags.
|
|
965
|
+
|
|
966
|
+
Flag SWAP_CW_CCW is required for CCW.'''
|
|
967
|
+
|
|
968
|
+
IGNORE_SWITCH = 0x01
|
|
969
|
+
'''Ignore switch or switch not present'''
|
|
970
|
+
MAKES_ON_CONTACT = 0x02
|
|
971
|
+
'''Switch makes on contact'''
|
|
972
|
+
BREAKS_ON_CONTACT = 0x03
|
|
973
|
+
'''Switch breaks on contact'''
|
|
974
|
+
MAKES_ON_CONTACT_HOMING = 0x04
|
|
975
|
+
'''Switch makes on contact (for homing)'''
|
|
976
|
+
BREAKS_ON_CONTACT_HOMING = 0x05
|
|
977
|
+
'''Switch breaks on contact (for homing)'''
|
|
978
|
+
INDEX_MARK_HOMING = 0x06
|
|
979
|
+
'''PMD based brushless servo controllers only, uses index mark for homing'''
|
|
980
|
+
SWAP_CW_CCW = 0x80
|
|
981
|
+
'''
|
|
982
|
+
Bitwise OR this with one of the settings above to swap CW and CCW limit switches
|
|
983
|
+
'''
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
class LimitSwitchMode(IntFlag):
|
|
987
|
+
'''Software limit switch mode.
|
|
988
|
+
|
|
989
|
+
Flag ROTATION_STAGE_LIMIT is required for rotation stage.'''
|
|
990
|
+
|
|
991
|
+
IGNORE_LIMIT = 0x01
|
|
992
|
+
'''Ignore limit'''
|
|
993
|
+
STOP_IMMEDIATE = 0x02
|
|
994
|
+
'''Stop immediately at limit'''
|
|
995
|
+
PROFILED_STOP = 0x03
|
|
996
|
+
'''Profiled stop at limit'''
|
|
997
|
+
ROTATION_STAGE_LIMIT = 0x80
|
|
998
|
+
'''
|
|
999
|
+
Bitwise OR this with one of the settings
|
|
1000
|
+
above to set rotation stage limit.
|
|
1001
|
+
|
|
1002
|
+
(Not applicable to TDC001 units)'''
|