cgse-coordinates 0.17.3__tar.gz → 0.17.4__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.
Files changed (26) hide show
  1. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/PKG-INFO +1 -1
  2. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/pyproject.toml +3 -3
  3. cgse_coordinates-0.17.4/src/cgse_coordinates/settings.yaml +0 -0
  4. cgse_coordinates-0.17.4/src/egse/coordinates/__init__.py +229 -0
  5. cgse_coordinates-0.17.4/src/egse/coordinates/avoidance.py +91 -0
  6. cgse_coordinates-0.17.4/src/egse/coordinates/cslmodel.py +118 -0
  7. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/src/egse/coordinates/laser_tracker_to_dict.py +16 -25
  8. cgse_coordinates-0.17.4/src/egse/coordinates/point.py +833 -0
  9. cgse_coordinates-0.17.4/src/egse/coordinates/pyplot.py +203 -0
  10. cgse_coordinates-0.17.4/src/egse/coordinates/reference_frame.py +1417 -0
  11. cgse_coordinates-0.17.4/src/egse/coordinates/refmodel.py +828 -0
  12. cgse_coordinates-0.17.4/src/egse/coordinates/rotation_matrix.py +95 -0
  13. cgse_coordinates-0.17.4/src/egse/coordinates/transform3d_addon.py +501 -0
  14. cgse_coordinates-0.17.3/src/cgse_coordinates/settings.yaml +0 -16
  15. cgse_coordinates-0.17.3/src/egse/coordinates/__init__.py +0 -536
  16. cgse_coordinates-0.17.3/src/egse/coordinates/avoidance.py +0 -99
  17. cgse_coordinates-0.17.3/src/egse/coordinates/cslmodel.py +0 -127
  18. cgse_coordinates-0.17.3/src/egse/coordinates/point.py +0 -707
  19. cgse_coordinates-0.17.3/src/egse/coordinates/pyplot.py +0 -191
  20. cgse_coordinates-0.17.3/src/egse/coordinates/referenceFrame.py +0 -1251
  21. cgse_coordinates-0.17.3/src/egse/coordinates/refmodel.py +0 -720
  22. cgse_coordinates-0.17.3/src/egse/coordinates/rotationMatrix.py +0 -82
  23. cgse_coordinates-0.17.3/src/egse/coordinates/transform3d_addon.py +0 -437
  24. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/.gitignore +0 -0
  25. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/README.md +0 -0
  26. {cgse_coordinates-0.17.3 → cgse_coordinates-0.17.4}/src/cgse_coordinates/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cgse-coordinates
3
- Version: 0.17.3
3
+ Version: 0.17.4
4
4
  Summary: Reference Frames and Coordinate Transofrmations for CGSE
5
5
  Author: IvS KU Leuven
6
6
  Maintainer-email: Rik Huygen <rik.huygen@kuleuven.be>, Sara Regibo <sara.regibo@kuleuven.be>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cgse-coordinates"
3
- version = "0.17.3"
3
+ version = "0.17.4"
4
4
  description = "Reference Frames and Coordinate Transofrmations for CGSE"
5
5
  authors = [
6
6
  {name = "IvS KU Leuven"}
@@ -28,8 +28,8 @@ dependencies = [
28
28
  [project.entry-points."cgse.version"]
29
29
  cgse-coordinates = 'egse.version:get_version_installed'
30
30
 
31
- [project.entry-points."cgse.settings"]
32
- cgse-coordinates = "cgse_coordinates:settings.yaml"
31
+ #[project.entry-points."cgse.settings"]
32
+ #cgse-coordinates = "cgse_coordinates:settings.yaml"
33
33
 
34
34
  [tool.pytest.ini_options]
35
35
  pythonpath = "src"
@@ -0,0 +1,229 @@
1
+ import ast
2
+ import logging
3
+ import re
4
+ from typing import Dict
5
+ from typing import List
6
+ from typing import Optional
7
+ from typing import Union
8
+
9
+ import numpy as np
10
+ from egse.setup import navdict
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ def dict_to_ref_model(model_def: Union[Dict, List]) -> navdict:
16
+ """Creates a reference frames model from a dictionary or list of reference frame definitions.
17
+
18
+ When a list is provided, the items in the list must be ReferenceFrames.
19
+
20
+ The reference frame definitions are usually read from a YAML file or returned by a Setup, but can also be just
21
+ ReferenceFrame objects.
22
+
23
+ ReferenceFrame definitions have the following format:
24
+
25
+ ```
26
+ ReferenceFrame://(<definition>)
27
+ ```
28
+ where `<definition>` has the following elements, separated by '` | `':
29
+ * a translation matrix
30
+ * a rotation matrix
31
+ * the name of the reference frame
32
+ * the name of the reference for this reference frame
33
+ * a dictionary of links
34
+
35
+ Args:
36
+ model_def (dict or list): Definition of the reference model.
37
+
38
+ Returns:
39
+ Dictionary representing the reference frames model.
40
+ """
41
+
42
+ ref_model = navdict()
43
+ ref_links = {}
44
+
45
+ from egse.coordinates.reference_frame import ReferenceFrame
46
+
47
+ def create_ref_frame(name, data) -> Union[ReferenceFrame, str]:
48
+ # This is a recursive function that creates a reference frame based on the given data.
49
+ # * When the data is already a ReferenceFrame, it just returns data
50
+ # * When data starts with the special string `ReferenceFrame//`, the data string is parsed
51
+ # and a corresponding ReferenceFrame is returned
52
+ # * When there is no match, the data is returned unaltered.
53
+ #
54
+ # SIDE EFFECT:
55
+ # * In the process, the outer ref-model and ref_links are updated.
56
+
57
+ if isinstance(data, ReferenceFrame):
58
+ return data
59
+
60
+ match = re.match(r"ReferenceFrame//\((.*)\)$", data)
61
+ if not match:
62
+ return data
63
+
64
+ translation, rotation, name, ref_name, links = match[1].split(" | ")
65
+
66
+ # All links are processed later
67
+
68
+ ref_links[name] = ast.literal_eval(links)
69
+
70
+ if ref_name == name == "Master":
71
+ ref_model.add(ref_name, ReferenceFrame.create_master())
72
+ return ref_model["Master"]
73
+
74
+ if ref_name not in ref_model:
75
+ ref_model.add(ref_name, create_ref_frame(ref_name, model_def[ref_name]))
76
+
77
+ ref_frame = ReferenceFrame.from_translation_rotation(
78
+ deserialize_array(translation),
79
+ deserialize_array(rotation),
80
+ name=name,
81
+ reference_frame=ref_model[ref_name],
82
+ )
83
+
84
+ return ref_frame
85
+
86
+ # if the given model_def is a list, turn it into a dict
87
+
88
+ if isinstance(model_def, list):
89
+ model_def = {frame.name: frame for frame in model_def}
90
+
91
+ for key, value in model_def.items():
92
+ if key not in ref_model:
93
+ ref_model.add(key, create_ref_frame(key, value))
94
+
95
+ # Process all the links
96
+
97
+ for ref_name, link_names in ref_links.items():
98
+ ref = ref_model[ref_name]
99
+ for link_name in link_names:
100
+ if link_name not in ref.linked_to:
101
+ ref.add_link(ref_model[link_name])
102
+
103
+ return ref_model
104
+
105
+
106
+ def ref_model_to_dict(ref_model) -> navdict:
107
+ """Creates a dictionary with reference frames definitions that define a reference model.
108
+
109
+ Args:
110
+ ref_model: A dictionary representing the reference frames model or a list of reference frames.
111
+
112
+ Returns:
113
+ Dictionary of reference frame definitions.
114
+ """
115
+
116
+ if isinstance(ref_model, dict):
117
+ ref_model = ref_model.values()
118
+
119
+ # take each key (which is a reference frame) and serialize it
120
+
121
+ model_def = {}
122
+
123
+ for ref in ref_model:
124
+ translation, rotation = ref.get_translation_rotation_vectors()
125
+ links = [ref.name for ref in ref.linked_to]
126
+ model_def[ref.name] = (
127
+ f"ReferenceFrame//("
128
+ f"{serialize_array(translation, precision=6)} | "
129
+ f"{serialize_array(rotation, precision=6)} | "
130
+ f"{ref.name} | "
131
+ f"{ref.reference_frame.name} | "
132
+ f"{links})"
133
+ )
134
+
135
+ return navdict(model_def)
136
+
137
+
138
+ def serialize_array(arr: Union[np.ndarray, list], precision: int = 4) -> str:
139
+ """Returns a string representation of a numpy array.
140
+
141
+ >>> serialize_array([1,2,3])
142
+ '[1, 2, 3]'
143
+ >>> serialize_array([[1,2,3], [4,5,6]])
144
+ '[[1, 2, 3], [4, 5, 6]]'
145
+ >>> serialize_array([[1,2.2,3], [4.3,5,6]])
146
+ '[[1.0000, 2.2000, 3.0000], [4.3000, 5.0000, 6.0000]]'
147
+ >>> serialize_array([[1,2.2,3], [4.3,5,6]], precision=2)
148
+ '[[1.00, 2.20, 3.00], [4.30, 5.00, 6.00]]'
149
+
150
+ Args:
151
+ arr: One- or-two dimensional numpy array or list.
152
+ precision (int): number of digits of precision
153
+ Returns:
154
+ A string representing the input array.
155
+ """
156
+ if isinstance(arr, list):
157
+ arr = np.array(arr)
158
+ msg = np.array2string(
159
+ arr,
160
+ separator=", ",
161
+ suppress_small=True,
162
+ formatter={"float_kind": lambda x: f"{x:.{precision}f}"},
163
+ ).replace("\n", "")
164
+ return msg
165
+
166
+
167
+ def deserialize_array(arr_str: str) -> Optional[np.ndarray]:
168
+ """Returns a numpy array from the given string.
169
+
170
+ The input string is interpreted as a one or two-dimensional array, with commas or spaces separating the columns,
171
+ and semicolons separating the rows.
172
+
173
+ >>> deserialize_array('1,2,3')
174
+ array([1, 2, 3])
175
+ >>> deserialize_array('1 2 3')
176
+ array([1, 2, 3])
177
+ >>> deserialize_array('1,2,3;4,5,6')
178
+ array([[1, 2, 3],
179
+ [4, 5, 6]])
180
+ >>> deserialize_array("[[1,2,3], [4,5,6]]")
181
+ array([[1, 2, 3],
182
+ [4, 5, 6]])
183
+
184
+ Args:
185
+ arr_str: String representation of a numpy array.
186
+
187
+ Returns:
188
+ One- or two-dimensional numpy array or `None` when input string cannot be parsed into a numpy array.
189
+ """
190
+
191
+ import re
192
+
193
+ arr_str = re.sub(r"\],\s*\[", "];[", arr_str)
194
+ try:
195
+ arr = np.array(_convert_from_string(arr_str))
196
+ return arr if ";" in arr_str else arr.flatten()
197
+ except ValueError as exc:
198
+ logger.error(f"Input string could not be parsed into a numpy array: {exc}")
199
+ return None
200
+
201
+
202
+ def _convert_from_string(data: str) -> list[list]:
203
+ # This function was copied from:
204
+ # https://github.com/numpy/numpy/blob/v1.19.0/numpy/matrixlib/defmatrix.py#L14
205
+ # We include the function here because the np.matrix class is deprecated and will be removed.
206
+ # This function is what we actually needed from np.matrix.
207
+
208
+ # This function can be replaced with np.fromstring()
209
+
210
+ for char in "[]":
211
+ data = data.replace(char, "")
212
+
213
+ rows = data.split(";")
214
+ new_data = []
215
+ count = 0
216
+ for row in rows:
217
+ trow = row.split(",")
218
+ new_row = []
219
+ for col in trow:
220
+ temp = col.split()
221
+ new_row.extend(map(ast.literal_eval, temp))
222
+ if count == 0:
223
+ n_cols = len(new_row)
224
+ elif len(new_row) != n_cols:
225
+ raise ValueError("Rows not the same size.")
226
+ count += 1
227
+ new_data.append(new_row)
228
+
229
+ return new_data
@@ -0,0 +1,91 @@
1
+ import numpy as np
2
+
3
+ from egse.coordinates.point import Points
4
+ from egse.coordinates.reference_frame import ReferenceFrame
5
+ from egse.setup import Setup, load_setup
6
+
7
+
8
+ def is_avoidance_ok(hexusr: ReferenceFrame, hexobj: ReferenceFrame, setup: Setup = None, verbose: bool = False):
9
+ """Checks whether the FPA is outside the avoidance volume around L6.
10
+
11
+ This function is used to verify that a requested movement of the PUNA hexapod will not cause the FPA to enter the
12
+ avoidance volume around L6.
13
+
14
+
15
+ Args:
16
+ hexusr (ReferenceFrame): User Reference Frame for the PUNA hexapod. Its xy-plane corresponds to the maximum
17
+ height of FPA_SEN. Its z-axis points away from the FPA.
18
+ hexobj (ReferenceFrame): Object Reference Frame for the PUNA hexapod. Its xy-plane coincides with FPA_SEN. Its
19
+ z-axis points towards L6.
20
+ setup (Setup): Setup object containing the default reference frames.
21
+ verbose (bool): Indicates whether to print verbose output.
22
+
23
+ Returns:
24
+ True if the FPA is outside the avoidance volume around L6; False otherwise.
25
+ """
26
+
27
+ setup = setup or load_setup()
28
+
29
+ # A. HORIZONTAL AVOIDANCE
30
+ # Ensure that the centre of L6, materialised by HEX_USR (incl. z-direction security wrt TOU_L6) stays within a
31
+ # given radius of the origin of FPA_SEN
32
+
33
+ # Clearance = the tolerance in every horizontal direction (3 mm; PLATO-KUL-PL-ICD-0001 v1.2)
34
+ clearance_xy = setup.camera.fpa.avoidance.clearance_xy
35
+
36
+ # Projection of the origin of HEX_USR on the xy-plane of FPA_SEN
37
+ l6xy = hexusr.get_origin().express_in(hexobj)[:2]
38
+
39
+ # !! This is a verification of the current situation
40
+ # -> need to replace by a simulation of the forthcoming movement in the building block
41
+ horizontal_check = (l6xy[0] ** 2.0 + l6xy[1] ** 2.0) < clearance_xy * clearance_xy
42
+
43
+ # B. VERTICAL AVOIDANCE
44
+ # Ensure that the CCD never hits L6.
45
+ # - The definition of HEX_USR includes a tolerance below L6 (1.65 mm).
46
+ # - We include a tolerance above FPA_SEN here (0.3 mm).
47
+ # - We define a collection of points to act at the vertices. of the avoidance volume above the FPA
48
+
49
+ # Clearance = vertical uncertainty on the CCD location (0.3 mm; PLATO-KUL-PL-ICD-0001 v1.2)
50
+ clearance_z = setup.camera.fpa.avoidance.clearance_z
51
+
52
+ # Vertices = Points representing the vertices of the avoidance volume above the FPA (60)
53
+ vertices_nb = setup.camera.fpa.avoidance.vertices_nb
54
+ # All vertices are on a circle of radius 'vertices_radius' (100 mm)
55
+ vertices_radius = setup.camera.fpa.avoidance.vertices_radius
56
+
57
+ angles = np.linspace(0, np.pi * 2, vertices_nb, endpoint=False)
58
+ vertices_x = np.cos(angles) * vertices_radius
59
+ vertices_y = np.sin(angles) * vertices_radius
60
+ vertices_z = np.ones_like(angles) * clearance_z
61
+
62
+ # The collection of points defining the avoidance volume around FPA_SEN
63
+
64
+ vert_obj = Points(
65
+ coordinates=np.array([vertices_x, vertices_y, vertices_z]), reference_frame=hexobj, name="vert_obj"
66
+ )
67
+
68
+ # Their coordinates in HEX_USR
69
+ # NB: vert_obj is a Points object, vert_usr is an array
70
+ vert_usr = vert_obj.express_in(hexusr)
71
+
72
+ # !! Same as above : this is verifying the current situation, not the one after a planned movement
73
+ # Verify that all vertices ("protecting" FPA_SEN) are below the x-y plane of HEX_USR ("protecting" L6)
74
+ vertical_check = np.all(vert_usr[2, :] < 0.0)
75
+
76
+ if verbose:
77
+ printdict = {True: "OK", False: "NOT OK"}
78
+ print(f"HORIZONTAL AVOIDANCE: {printdict[horizontal_check]}")
79
+ print(f" VERTICAL AVOIDANCE: {printdict[vertical_check]}")
80
+
81
+ if verbose > 1:
82
+ print(f"Points Coordinates")
83
+ coobj = vert_obj.coordinates
84
+ for i in range(vertices_nb):
85
+ print(f"{i} OBJ {np.round(coobj[:3, i], 6)} --> USR {np.round(vert_usr[:3, i], 6)}")
86
+ vert_z = vert_usr[2, :]
87
+ vert_zi = np.where(vert_z == np.max(vert_z))
88
+ print(f"#vertices at max z : {len(vert_zi[0])}")
89
+ print(f"First one: vertex {vert_zi[0][0]} : {np.round(vert_usr[:3, vert_zi[0][0]], 6)}")
90
+
91
+ return horizontal_check and vertical_check
@@ -0,0 +1,118 @@
1
+ """
2
+ A CSL reference frame model which has knowledge about the CSL Setup, and the PUNA Hexapod model.
3
+
4
+ The CSL Reference Frame Model incorporates a Hexapod PUNA model which is represented by the
5
+ Reference Frames HEXUSR, HEXOBJ, HEXMEC, and HEXPLT. A number of methods are defined here that
6
+ assume these four reference frames exist in the model and behave like a proper hexapod simulator.
7
+ Those methods start with the name `hexapod_`, e.g. `hexapod_goto_zero_position()`.
8
+
9
+ """
10
+
11
+ import numpy as np
12
+ from egse.coordinates.refmodel import ReferenceFrameModel
13
+
14
+ HEXUSR = "hexusr"
15
+ HEXMEC = "hexmec"
16
+ HEXOBJ = "hexobj"
17
+ HEXPLT = "hexplt"
18
+ HEXOBUSR = "hexobusr"
19
+
20
+
21
+ class CSLReferenceFrameModel(ReferenceFrameModel):
22
+ """
23
+ The CSL reference Frame Model is a specific reference model that adds convenience methods for manipulating the
24
+ Hexapod PUNA which is part of the overall CSL Setup.
25
+ """
26
+
27
+ _DEGREES_DEFAULT = ReferenceFrameModel._DEGREES_DEFAULT
28
+
29
+ def _create_obusr(self) -> None:
30
+ """Creates the Object User Reference Frame if it does not exist yet."""
31
+
32
+ if HEXOBUSR in self:
33
+ return
34
+
35
+ hexusr = self.get_frame(HEXUSR)
36
+ hexobj = self.get_frame(HEXOBJ)
37
+
38
+ transformation = hexusr.get_active_transformation_to(hexobj)
39
+
40
+ self.add_frame(HEXOBUSR, transformation=transformation, reference=HEXUSR)
41
+ self.add_link(HEXOBUSR, HEXOBJ)
42
+
43
+ def hexapod_move_absolute(self, translation: np.ndarray, rotation: np.ndarray, degrees: bool = _DEGREES_DEFAULT):
44
+ """Moves/defines the Object Coordinate System expressed in the invariant User Coordinate System.
45
+
46
+ The rotation centre coincides with the Object Coordinates System origin and the movements are controlled with
47
+ translation components first (Tx, Ty, tZ) and then the rotation components (Rx, Ry, Rz).
48
+
49
+ Args:
50
+ translation (np.ndarray): Translation vector.
51
+ rotation (np.ndarray): Rotation vector.
52
+ degrees (bool): Indicates whether the rotation angles are specified in degrees, rather than radians.
53
+ """
54
+
55
+ self.move_absolute_self(HEXOBUSR, translation, rotation, degrees=degrees)
56
+
57
+ def hexapod_move_relative_object(
58
+ self, translation: np.ndarray, rotation: np.ndarray, degrees: bool = _DEGREES_DEFAULT
59
+ ):
60
+ """Moves the object relative to its current position and orientation
61
+
62
+ The relative movement is expressed in the object coordinate system.
63
+
64
+ Args:
65
+ translation (np.ndarray): Translation vector.
66
+ rotation (np.ndarray): Rotation vector.
67
+ degrees (bool): Indicates whether the rotation angles are specified in degrees, rather than radians.
68
+ """
69
+
70
+ self.move_relative_self(HEXOBJ, translation, rotation, degrees=degrees)
71
+
72
+ def hexapod_move_relative_user(
73
+ self, translation: np.ndarray, rotation: np.ndarray, degrees: bool = _DEGREES_DEFAULT
74
+ ) -> None:
75
+ """Moves the object relative to its current object position and orientation.
76
+
77
+ The relative movement is expressed in the (invariant) user coordinate system.
78
+
79
+ Args:
80
+ translation (np.ndarray): Translation vector.
81
+ rotation (np.ndarray): Rotation vector.
82
+ degrees (bool): Indicates whether the rotation angles are specified in degrees, rather than radians.
83
+ """
84
+
85
+ self.move_relative_other_local(HEXOBJ, HEXUSR, translation, rotation, degrees=degrees)
86
+
87
+ def hexapod_configure_coordinates(
88
+ self,
89
+ usr_trans: np.ndarray,
90
+ usr_rot: np.ndarray,
91
+ obj_trans: np.ndarray,
92
+ obj_rot: np.ndarray,
93
+ ) -> None:
94
+ """Changes the definition of the User Coordinate System and the Object Coordinate System in the hexapod.
95
+
96
+ Args:
97
+ usr_trans (np.ndarray): Translation vector used to define the User Coordinate System relative to the Machine Coordinate System.
98
+ usr_rot (np.ndarray): Rotation vector used to define the User Coordinate System relative to the Machine Coordinate System.
99
+ obj_trans (np.ndarray): Translation vector used to define the Object Coordinate System relative to the Platform Coordinate System.
100
+ obj_rot (np.ndarray): Rotation vector used to define the Object Coordinate System relative to the Platoform Coordinate System.
101
+ """
102
+
103
+ self.remove_link(HEXUSR, HEXMEC)
104
+ self.remove_link(HEXOBJ, HEXPLT)
105
+ self.get_frame(HEXUSR).set_translation_rotation(usr_trans, usr_rot)
106
+ self.get_frame(HEXOBJ).set_translation_rotation(obj_trans, obj_rot)
107
+ self.add_link(HEXUSR, HEXMEC)
108
+ self.add_link(HEXOBJ, HEXPLT)
109
+
110
+ def hexapod_goto_zero_position(self) -> None:
111
+ """Instructs the hexapod to go to its zero position"""
112
+
113
+ self.move_absolute_self(HEXPLT, translation=np.array([0, 0, 0]), rotation=np.array([0, 0, 0]))
114
+
115
+ def hexapod_goto_retracted_position(self) -> None:
116
+ """Instructs the hexapod to go to its retracted position."""
117
+
118
+ self.move_absolute_self(HEXPLT, translation=np.array([0, 0, -20]), rotation=np.array([0, 0, 0]))
@@ -1,28 +1,15 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- Created on Sat Oct 3 11:53:23 2020
5
-
6
- @author: pierre
7
- """
8
-
9
1
  import sys
10
2
  import pandas
11
3
 
12
4
  from egse.setup import Setup
13
5
 
14
6
 
15
- def laser_tracker_to_dict(filexls, setup: Setup):
16
- """
17
- laser_tracker_to_dict(filexls)
18
-
19
- INPUT
20
-
21
- filexls : CSL - provided excell file (from a laser tracker)
22
-
23
- OUTPUT
7
+ def laser_tracker_to_dict(file_xls: str, setup: Setup):
8
+ """Reads the laser tracker file and returns a dictionary of reference frames.
24
9
 
25
- dictionary compatible with egse.coordinates.dict_to_ref_model
10
+ Args:
11
+ file_xls (str): Path to the laser tracker file. This is an excell sheet provided by CSL.
12
+ setup (Setup): Setup object containing the default reference frames.
26
13
 
27
14
  Known Features:
28
15
  - no link can be included:
@@ -37,6 +24,8 @@ def laser_tracker_to_dict(filexls, setup: Setup):
37
24
  - the names of the reference frames are returned lowercase, without '_'
38
25
  ("Master" is an exception)
39
26
 
27
+ Returns:
28
+ Dictionary of reference frames compatible with egse.coordinates.dict_to_ref_model.
40
29
  """
41
30
 
42
31
  # Predefined model -- gliso ~ master
@@ -72,22 +61,24 @@ def laser_tracker_to_dict(filexls, setup: Setup):
72
61
 
73
62
  # Read input file
74
63
 
75
- pan = pandas.read_excel(filexls, sheet_name="Data", usecols="A:D", names=["desc", "x", "y", "z"])
64
+ pan = pandas.read_excel(file_xls, sheet_name="Data", usecols="A:D", names=["desc", "x", "y", "z"])
76
65
 
77
- nrows = pan.shape[0]
66
+ num_rows = pan.shape[0]
78
67
 
79
68
  desc = pan["desc"].values
80
69
  colx = pan["x"].values
81
70
  coly = pan["y"].values
82
71
  colz = pan["z"].values
83
72
 
84
- refFrames = dict()
85
- refFrames["Master"] = "ReferenceFrame//([0.0000,0.0000,0.0000 | [0.0000,0.0000,0.0000 | Master | Master | [])"
73
+ reference_frames = dict()
74
+ reference_frames["Master"] = (
75
+ "ReferenceFrame//([0.0000,0.0000,0.0000 | [0.0000,0.0000,0.0000 | Master | Master | [])"
76
+ )
86
77
 
87
78
  links = "[]"
88
79
 
89
80
  i, frame = -1, -1
90
- while i < nrows:
81
+ while i < num_rows:
91
82
  i += 1
92
83
 
93
84
  try:
@@ -111,10 +102,10 @@ def laser_tracker_to_dict(filexls, setup: Setup):
111
102
  else:
112
103
  ref = "None"
113
104
 
114
- refFrames[name] = f"ReferenceFrame//({translation} | {rotation} | {name} | {ref} | {links})"
105
+ reference_frames[name] = f"ReferenceFrame//({translation} | {rotation} | {name} | {ref} | {links})"
115
106
 
116
107
  except:
117
108
  print(f"Frame extraction issue after row {i} : {desc[i]}")
118
109
  print(sys.exc_info())
119
110
 
120
- return refFrames
111
+ return reference_frames