symetrie-hexapod 2023.1.0__tar.gz
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.
- symetrie_hexapod-2023.1.0/PKG-INFO +10 -0
- symetrie_hexapod-2023.1.0/pyproject.toml +36 -0
- symetrie_hexapod-2023.1.0/setup.cfg +4 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/__init__.py +32 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/__init__.py +151 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/alpha.py +874 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/dynalpha.py +1384 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/hexapod_ui.py +1509 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/pmac.py +1010 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/pmac_regex.py +83 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/puna.py +1167 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/puna.yaml +193 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/puna_cs.py +197 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/puna_protocol.py +131 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/puna_ui.py +432 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/punaplus.py +107 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda.py +872 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda.yaml +337 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda_cs.py +172 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda_devif.py +415 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda_protocol.py +119 -0
- symetrie_hexapod-2023.1.0/src/egse/hexapod/symetrie/zonda_ui.py +448 -0
- symetrie_hexapod-2023.1.0/src/scripts/cgse_service_plugins.py +27 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/PKG-INFO +10 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/SOURCES.txt +27 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/dependency_links.txt +1 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/entry_points.txt +11 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/requires.txt +5 -0
- symetrie_hexapod-2023.1.0/src/symetrie_hexapod.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: symetrie-hexapod
|
|
3
|
+
Version: 2023.1.0
|
|
4
|
+
Summary: Symetrie Hexapod implementation for CGSE
|
|
5
|
+
License: Common-EGSE Software License Agreement
|
|
6
|
+
Requires-Dist: cgse-common
|
|
7
|
+
Requires-Dist: cgse-core
|
|
8
|
+
Requires-Dist: cgse-gui
|
|
9
|
+
Requires-Dist: cgse-coordinates
|
|
10
|
+
Requires-Dist: PyQt5
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "setuptools-scm"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools.packages.find]
|
|
6
|
+
where = ["src"]
|
|
7
|
+
include = ["egse", "egse.hexapod.symetrie"]
|
|
8
|
+
namespaces = true
|
|
9
|
+
|
|
10
|
+
[tool.setuptools.package-data]
|
|
11
|
+
egse = ["*.yaml"]
|
|
12
|
+
|
|
13
|
+
[project]
|
|
14
|
+
name = "symetrie-hexapod"
|
|
15
|
+
version = "2023.1.0"
|
|
16
|
+
description = "Symetrie Hexapod implementation for CGSE"
|
|
17
|
+
license = { text = "Common-EGSE Software License Agreement" }
|
|
18
|
+
dependencies = [
|
|
19
|
+
"cgse-common",
|
|
20
|
+
"cgse-core",
|
|
21
|
+
"cgse-gui",
|
|
22
|
+
"cgse-coordinates",
|
|
23
|
+
"PyQt5",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
puna_cs = 'egse.hexapod.symetrie.puna_cs:cli'
|
|
28
|
+
|
|
29
|
+
[project.gui-scripts]
|
|
30
|
+
puna_ui = "egse.hexapod.symetrie.puna_ui:main"
|
|
31
|
+
|
|
32
|
+
[project.entry-points."cgse.version"]
|
|
33
|
+
symetrie-hexapod = 'egse.plugins'
|
|
34
|
+
|
|
35
|
+
[project.entry-points."cgse.service.plugins"]
|
|
36
|
+
puna_cs = 'scripts.cgse_service_plugins:puna_cs'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The Hexapod package provides the components to interact with the PUNA Hexapod of
|
|
3
|
+
Symétrie, i.e.
|
|
4
|
+
|
|
5
|
+
* The Hexapod commanding concept with Command, and CommandProtocol
|
|
6
|
+
* The client server access through Proxy and ControlServer
|
|
7
|
+
* The interface to the hardware controller: HexapodController and its simulator
|
|
8
|
+
|
|
9
|
+
This package also contains the Hexapod GUI which can be used to monitor the
|
|
10
|
+
hexapod positions in different reference frames and apply simple movements.
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HexapodError(Exception):
|
|
16
|
+
"""A Hexapod specific error."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# These are the classes and function that we would like to export. This is mainly
|
|
21
|
+
# to simplify import statements in scripts. The user can now use the following:
|
|
22
|
+
#
|
|
23
|
+
# >>> from egse.hexapod import HexapodProxy
|
|
24
|
+
#
|
|
25
|
+
# while she previously had to import the class as follows:
|
|
26
|
+
#
|
|
27
|
+
# >>> from egse.hexapod.hexapodProxy import HexapodProxy
|
|
28
|
+
#
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
'HexapodError',
|
|
32
|
+
]
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Device control for the Symétrie Hexapod PUNA and ZONDA.
|
|
3
|
+
|
|
4
|
+
This package contains the modules and classes to work with the Hexapod PUNA and the Hexapod ZONDA
|
|
5
|
+
from [Symétrie](www.symetrie.fr).
|
|
6
|
+
|
|
7
|
+
The main entry point for the user of this package is through the terminal commands to start the
|
|
8
|
+
control servers for the PUNA and ZONDA Hexapod, and the GUIs that are provided to interact with
|
|
9
|
+
the hexapods. The following commands start the control servers for both the PUNA and the ZONDA
|
|
10
|
+
in the background.
|
|
11
|
+
|
|
12
|
+
$ puna_cs start-bg
|
|
13
|
+
$ zonda_cs start-bg
|
|
14
|
+
|
|
15
|
+
The GUIs can be started with the following commands:
|
|
16
|
+
|
|
17
|
+
$ puna_ui
|
|
18
|
+
$ zonda_ui
|
|
19
|
+
|
|
20
|
+
For developers, the `PunaProxy` and `ZondaProxy` classes are the main interface to command the
|
|
21
|
+
hardware.
|
|
22
|
+
|
|
23
|
+
>>> from egse.hexapod.symetrie.puna import PunaProxy
|
|
24
|
+
>>> puna = PunaProxy()
|
|
25
|
+
|
|
26
|
+
and for the ZONDA:
|
|
27
|
+
|
|
28
|
+
>>> from egse.hexapod.symetrie.zonda import ZondaProxy
|
|
29
|
+
>>> zonda = ZondaProxy()
|
|
30
|
+
|
|
31
|
+
These classes will connect to their control servers and provide all commands to
|
|
32
|
+
control the hexapod and monitor its positions and status.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
import os
|
|
37
|
+
|
|
38
|
+
from egse.device import DeviceFactoryInterface
|
|
39
|
+
from egse.settings import Settings, SettingsError
|
|
40
|
+
|
|
41
|
+
PUNA_SETTINGS = Settings.load("PMAC Controller")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_hexapod_controller_pars(setup: 'Setup' = None) -> (str, int, str, str, str):
|
|
45
|
+
"""
|
|
46
|
+
Returns the hostname (str), port number (int), hexapod id (str), hexapod name (str),
|
|
47
|
+
and type (str) for the hexapod controller as defined in the Setup and Settings.
|
|
48
|
+
|
|
49
|
+
Note the returned values are for the device hardware controller, not the control server.
|
|
50
|
+
|
|
51
|
+
If no setup argument is provided, the Setup will be loaded from the GlobalState.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
from egse.setup import SetupError, load_setup
|
|
55
|
+
|
|
56
|
+
setup = setup or load_setup()
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
try:
|
|
60
|
+
hexapod_id = setup.gse.hexapod.device_args.device_id
|
|
61
|
+
hexapod_name: str = setup.gse.hexapod.device_args.device_name
|
|
62
|
+
except AttributeError:
|
|
63
|
+
# Handle older Setups where no device_args existed for the PUNA hexapod
|
|
64
|
+
hexapod_id = setup.gse.hexapod.ID
|
|
65
|
+
hexapod_name: str = setup.gse.hexapod.device_name
|
|
66
|
+
except AttributeError as exc:
|
|
67
|
+
|
|
68
|
+
# Before quitting, try to load from environment variables
|
|
69
|
+
|
|
70
|
+
hexapod_id = os.environ.get("SYMETRIE_HEXAPOD_ID")
|
|
71
|
+
hexapod_name = os.environ.get("SYMETRIE_HEXAPOD_NAME")
|
|
72
|
+
|
|
73
|
+
if hexapod_id is None or hexapod_name is None:
|
|
74
|
+
raise SetupError("The Setup doesn't contain proper controller parameters for the Hexapod.") from exc
|
|
75
|
+
|
|
76
|
+
hexapod_id = f"H_{hexapod_id}"
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
hostname: str = PUNA_SETTINGS[hexapod_id]["HOSTNAME"]
|
|
80
|
+
port: int = int(PUNA_SETTINGS[hexapod_id]["PORT"])
|
|
81
|
+
controller_type: str = PUNA_SETTINGS[hexapod_id]["TYPE"]
|
|
82
|
+
except (KeyError, AttributeError) as exc:
|
|
83
|
+
raise SettingsError("The Settings do not contain proper controller parameters for the Hexapod.") from exc
|
|
84
|
+
|
|
85
|
+
return hostname, port, hexapod_id, hexapod_name, controller_type
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ProxyFactory(DeviceFactoryInterface):
|
|
89
|
+
"""
|
|
90
|
+
A factory class that will create the Proxy that matches the given device name and identifier.
|
|
91
|
+
|
|
92
|
+
The device name is matched against the string 'puna' or 'zonda'. If the device name doesn't contain
|
|
93
|
+
one of these names, a ValueError will be raised.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
def create(self, device_name: str, *, device_id: str = None, **_ignored):
|
|
97
|
+
|
|
98
|
+
if "puna" in device_name.lower():
|
|
99
|
+
if not device_id.startswith("H_"):
|
|
100
|
+
device_id = f"H_{device_id}"
|
|
101
|
+
|
|
102
|
+
controller_type = PUNA_SETTINGS[device_id]["TYPE"]
|
|
103
|
+
if controller_type == "ALPHA":
|
|
104
|
+
from egse.hexapod.symetrie.puna import PunaProxy
|
|
105
|
+
return PunaProxy()
|
|
106
|
+
elif controller_type == "ALPHA_PLUS":
|
|
107
|
+
from egse.hexapod.symetrie.punaplus import PunaPlusProxy
|
|
108
|
+
return PunaPlusProxy()
|
|
109
|
+
else:
|
|
110
|
+
raise ValueError(f"Unknown controller_type ({controller_type}) for {device_name} – {device_id}")
|
|
111
|
+
|
|
112
|
+
elif "zonda" in device_name.lower():
|
|
113
|
+
from egse.hexapod.symetrie.zonda import ZondaProxy
|
|
114
|
+
return ZondaProxy()
|
|
115
|
+
|
|
116
|
+
else:
|
|
117
|
+
raise ValueError(f"Unknown device name: {device_name}")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class ControllerFactory(DeviceFactoryInterface):
|
|
121
|
+
"""
|
|
122
|
+
A factory class that will create the Controller that matches the given device name and identifier.
|
|
123
|
+
|
|
124
|
+
The device name is matched against the string 'puna' or 'zonda'. If the device name doesn't contain
|
|
125
|
+
one of these names, a ValueError will be raised.
|
|
126
|
+
"""
|
|
127
|
+
def create(self, device_name: str, *, device_id: str = None, **_ignored):
|
|
128
|
+
|
|
129
|
+
if "puna" in device_name.lower():
|
|
130
|
+
from egse.hexapod.symetrie.puna import PunaController
|
|
131
|
+
from egse.hexapod.symetrie.punaplus import PunaPlusController
|
|
132
|
+
|
|
133
|
+
if not device_id.startswith("H_"):
|
|
134
|
+
device_id = f"H_{device_id}"
|
|
135
|
+
|
|
136
|
+
hostname = PUNA_SETTINGS[device_id]["HOSTNAME"]
|
|
137
|
+
port = PUNA_SETTINGS[device_id]["PORT"]
|
|
138
|
+
controller_type = PUNA_SETTINGS[device_id]["TYPE"]
|
|
139
|
+
if controller_type == "ALPHA":
|
|
140
|
+
return PunaController(hostname=hostname, port=port)
|
|
141
|
+
elif controller_type == "ALPHA_PLUS":
|
|
142
|
+
return PunaPlusController(hostname=hostname, port=port)
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError(f"Unknown controller_type ({controller_type}) for {device_name} – {device_id}")
|
|
145
|
+
|
|
146
|
+
elif "zonda" in device_name.lower():
|
|
147
|
+
from egse.hexapod.symetrie.zonda import ZondaController
|
|
148
|
+
return ZondaController()
|
|
149
|
+
|
|
150
|
+
else:
|
|
151
|
+
raise ValueError(f"Unknown device name: {device_name}")
|