micropsi-integration-sdk 0.24.0__tar.gz → 0.26.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.
Files changed (30) hide show
  1. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/PKG-INFO +80 -32
  2. micropsi-integration-sdk-0.24.0/micropsi_integration_sdk.egg-info/PKG-INFO → micropsi_integration_sdk-0.26.0/README.md +64 -46
  3. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/examples/cartesian_pose_robot.py +31 -19
  4. micropsi_integration_sdk-0.26.0/examples/cartesian_velocity_robot.py +98 -0
  5. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/examples/joint_position_robot.py +28 -19
  6. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/examples/joint_speed_robot.py +32 -19
  7. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/robot_interface_collection.py +2 -2
  8. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/robot_sdk.py +18 -0
  9. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/sandbox.py +192 -113
  10. micropsi_integration_sdk-0.26.0/micropsi_integration_sdk/sandbox_motion_generation.py +160 -0
  11. micropsi_integration_sdk-0.26.0/micropsi_integration_sdk/toolbox.py +138 -0
  12. micropsi_integration_sdk-0.26.0/micropsi_integration_sdk/version.py +1 -0
  13. micropsi-integration-sdk-0.24.0/README.md → micropsi_integration_sdk-0.26.0/micropsi_integration_sdk.egg-info/PKG-INFO +94 -29
  14. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk.egg-info/SOURCES.txt +1 -0
  15. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk.egg-info/requires.txt +1 -0
  16. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/setup.py +2 -2
  17. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/tests/test_example_robots.py +3 -7
  18. micropsi-integration-sdk-0.24.0/examples/cartesian_velocity_robot.py +0 -83
  19. micropsi-integration-sdk-0.24.0/micropsi_integration_sdk/toolbox.py +0 -38
  20. micropsi-integration-sdk-0.24.0/micropsi_integration_sdk/version.py +0 -1
  21. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/LICENSE.txt +0 -0
  22. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/MANIFEST.in +0 -0
  23. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/__init__.py +0 -0
  24. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/dev_client.py +0 -0
  25. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/dev_schema.py +0 -0
  26. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk/dev_server.py +0 -0
  27. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk.egg-info/dependency_links.txt +0 -0
  28. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk.egg-info/entry_points.txt +0 -0
  29. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/micropsi_integration_sdk.egg-info/top_level.txt +0 -0
  30. {micropsi-integration-sdk-0.24.0 → micropsi_integration_sdk-0.26.0}/setup.cfg +0 -0
@@ -1,19 +1,32 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: micropsi-integration-sdk
3
- Version: 0.24.0
3
+ Version: 0.26.0
4
4
  Summary: Integration SDK for Micropsi Industries
5
5
  Home-page: https://github.com/micropsi-industries/micropsi-integration-sdk
6
6
  Author: Micropsi Industries
7
7
  Author-email: contact@micropsi-industries.com
8
8
  License: MIT
9
- Platform: macosx-14-arm64
10
- Requires-Python: >=3.6, <4
9
+ Platform: macosx-15-arm64
10
+ Requires-Python: >=3.10, <4
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE.txt
13
13
  Requires-Dist: numpy
14
14
  Requires-Dist: pyquaternion
15
+ Requires-Dist: scipy
15
16
  Provides-Extra: test
16
17
  Requires-Dist: pytest; extra == "test"
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license
24
+ Dynamic: license-file
25
+ Dynamic: platform
26
+ Dynamic: provides-extra
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
17
30
 
18
31
  # Micropsi Industries Integration SDK
19
32
  Package for implementing and testing robots to be integrated with Mirai.
@@ -50,50 +63,85 @@ hardware.
50
63
  They can be used as a starting point when developing a new robot implementation.
51
64
 
52
65
  ## Mirai sandbox
53
- Standalone tool to test the SDK-based Robot control implementation.
54
- Moves the robot and verifies the implementation of methods described in Robot SDK. In particular
55
- the implementation of the high-frequency control loop.
56
- The direction (x, y or z axis) and length of the test movement can be configured.
57
- ```bash
58
- usage: mirai-sandbox [-h] [-m MODEL] [-sl SPEED_LINEAR] [-sa SPEED_ANGULAR]
59
- [-d DIMENSION] [-l LENGTH] [-ip IP_ADDRESS]
60
- [-tl TOLERANCE_LINEAR] [-ta TOLERANCE_ANGULAR] [-v]
66
+ Standalone tool to test an SDK-based robot interface implementation. This will attempt
67
+ to read robot poses and send movement commands in ways similar to Mirai, helping to
68
+ uncover problems related to geometry and real time control.
69
+
70
+ If successful, the robot will go through a defined sequence of tool pose changes
71
+ and return to its start pose. See `--help` or below for details.
72
+
73
+ **CAUTION**
74
+ This will attempt to move the robot. Although this tool (by default) only
75
+ outputs low-speed commands, prepare for unexpected behavior including large,
76
+ high-speed movements when testing with a newly written interface.
77
+
78
+ ```
79
+ usage: mirai-sandbox [-h] [-m MODEL] [-ip IP_ADDRESS] [-sl SPEED_LINEAR] [-sa SPEED_ROTATION] [--test [{translations,single-rotations,chained-rotations} ...]] [--max-distance-translation MAX_DISTANCE_TRANSLATION]
80
+ [--max-distance-degrees MAX_DISTANCE_DEGREES] [-tl TOLERANCE_LINEAR] [-ta TOLERANCE_ROTATION] [-v] [-d DIMENSION] [-l LENGTH]
61
81
  path
62
82
 
63
- Micropsi Industries Robot SDK Tool
83
+ This will attempt to read poses and execute movements on a given robot interface.
84
+
85
+ Expected outcome: The robot moves through the following sequence of waypoints,
86
+ and ends up back at the start pose:
87
+
88
+ # translations:
89
+ 1. Translate in tool +X by a set amount, then -X by the same amount (= return to origin)
90
+ 2. Similar for tool +/- Y
91
+ 3. Similar for tool +/- Z
92
+ # single rotations:
93
+ 4. Rotate around tool +X by a set amount, then -X (= return to origin)
94
+ 5. Similar for tool +/- Y
95
+ 6. Similar for tool +/- Z
96
+ 7. Rotate around the tool XY diagonal, then return
97
+ 8. Similar for the YZ diagonal
98
+ 9. Similar for the XZ diagonal
99
+ # chained rotations:
100
+ 10. Rotate around tool Z, then Y, then X; then return in the reverse order.
101
+
102
+ See --help for config options (e.g. range of motion, speed, including/excluding some of the motions)
64
103
 
65
104
  positional arguments:
66
105
  path Path to the robot implementation
67
106
 
68
- optional arguments:
107
+ options:
69
108
  -h, --help show this help message and exit
70
109
  -m MODEL, --model MODEL
71
110
  Name of the robot model as defined in the implementation.
72
- -sl SPEED_LINEAR, --speed-linear SPEED_LINEAR
73
- Linear end-effector speed, meters per second.
74
- Default: 0.05, Max: 0.1
75
- -sa SPEED_ANGULAR, --speed-angular SPEED_ANGULAR
76
- Angular end-effector speed, radians per second.
77
- Default: 0.2617993877991494, Max: 0.6981317007977318
78
- -d DIMENSION, --dimension DIMENSION
79
- Number of axes to move the robot in.
80
- Default: 1
81
- -l LENGTH, --length LENGTH
82
- Length of test movement, meters.
83
- Default:0.05, Max: 0.1m
84
111
  -ip IP_ADDRESS, --ip-address IP_ADDRESS
85
112
  IP address of the robot.
86
113
  Default: 192.168.100.100
114
+ -sl SPEED_LINEAR, --speed-linear SPEED_LINEAR
115
+ Linear end-effector speed, meters per second.
116
+ Default: 0.05
117
+ -sa SPEED_ROTATION, --speed-rotation SPEED_ROTATION
118
+ Rotational end-effector speed, degrees per second.
119
+ Default: 5.0°
120
+ --test [{translations,single-rotations,chained-rotations} ...]
121
+ Select which tests to run, can specify one or multiple.
122
+ Choices: translations, single-rotations, chained-rotations.
123
+ Default: run all.
124
+ --max-distance-translation MAX_DISTANCE_TRANSLATION
125
+ Maximum distance for translational movements, meters.
126
+ Default: 0.05
127
+ --max-distance-degrees MAX_DISTANCE_DEGREES
128
+ Maximum distance for rotational movements, degrees.
129
+ Default: 10.0°
87
130
  -tl TOLERANCE_LINEAR, --tolerance-linear TOLERANCE_LINEAR
88
- Linear tolerance of the end-effector position achieved by robot.
89
- Default: 0.001 meters
90
- -ta TOLERANCE_ANGULAR, --tolerance-angular TOLERANCE_ANGULAR
91
- Angular tolerance of the end-effector position achieved by robot.
92
- Default: 0.01 radians
131
+ Consider a position linearly reached when within this distance, meters
132
+ Default: 0.001m
133
+ -ta TOLERANCE_ROTATION, --tolerance-rotation TOLERANCE_ROTATION
134
+ Consider a position rotationally reached when within this distance, degrees
135
+ Default: 0.
93
136
  -v, --verbose Enable debug logging.
137
+ -d DIMENSION, --dimension DIMENSION
138
+ OBSOLETE: See --test
139
+ -l LENGTH, --length LENGTH
140
+ OBSOLETE: See --max-distance-translation and --max-distance-degrees
94
141
 
95
- Usage example: mirai-sandbox ./examples/cartesian_velocity_robot.py
142
+ Usage example: mirai-sandbox ../examples/cartesian_velocity_robot.py
96
143
  ```
144
+
97
145
  ## Mirai dev server
98
146
  This tool simulates a mirai controller in certain (very simplified) ways.
99
147
  Once started, it listens on port 6599 for the commands sent by either your PLC or robot program,
@@ -1,20 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: micropsi-integration-sdk
3
- Version: 0.24.0
4
- Summary: Integration SDK for Micropsi Industries
5
- Home-page: https://github.com/micropsi-industries/micropsi-integration-sdk
6
- Author: Micropsi Industries
7
- Author-email: contact@micropsi-industries.com
8
- License: MIT
9
- Platform: macosx-14-arm64
10
- Requires-Python: >=3.6, <4
11
- Description-Content-Type: text/markdown
12
- License-File: LICENSE.txt
13
- Requires-Dist: numpy
14
- Requires-Dist: pyquaternion
15
- Provides-Extra: test
16
- Requires-Dist: pytest; extra == "test"
17
-
18
1
  # Micropsi Industries Integration SDK
19
2
  Package for implementing and testing robots to be integrated with Mirai.
20
3
  A brief introduction and command reference can be found here.
@@ -50,50 +33,85 @@ hardware.
50
33
  They can be used as a starting point when developing a new robot implementation.
51
34
 
52
35
  ## Mirai sandbox
53
- Standalone tool to test the SDK-based Robot control implementation.
54
- Moves the robot and verifies the implementation of methods described in Robot SDK. In particular
55
- the implementation of the high-frequency control loop.
56
- The direction (x, y or z axis) and length of the test movement can be configured.
57
- ```bash
58
- usage: mirai-sandbox [-h] [-m MODEL] [-sl SPEED_LINEAR] [-sa SPEED_ANGULAR]
59
- [-d DIMENSION] [-l LENGTH] [-ip IP_ADDRESS]
60
- [-tl TOLERANCE_LINEAR] [-ta TOLERANCE_ANGULAR] [-v]
36
+ Standalone tool to test an SDK-based robot interface implementation. This will attempt
37
+ to read robot poses and send movement commands in ways similar to Mirai, helping to
38
+ uncover problems related to geometry and real time control.
39
+
40
+ If successful, the robot will go through a defined sequence of tool pose changes
41
+ and return to its start pose. See `--help` or below for details.
42
+
43
+ **CAUTION**
44
+ This will attempt to move the robot. Although this tool (by default) only
45
+ outputs low-speed commands, prepare for unexpected behavior including large,
46
+ high-speed movements when testing with a newly written interface.
47
+
48
+ ```
49
+ usage: mirai-sandbox [-h] [-m MODEL] [-ip IP_ADDRESS] [-sl SPEED_LINEAR] [-sa SPEED_ROTATION] [--test [{translations,single-rotations,chained-rotations} ...]] [--max-distance-translation MAX_DISTANCE_TRANSLATION]
50
+ [--max-distance-degrees MAX_DISTANCE_DEGREES] [-tl TOLERANCE_LINEAR] [-ta TOLERANCE_ROTATION] [-v] [-d DIMENSION] [-l LENGTH]
61
51
  path
62
52
 
63
- Micropsi Industries Robot SDK Tool
53
+ This will attempt to read poses and execute movements on a given robot interface.
54
+
55
+ Expected outcome: The robot moves through the following sequence of waypoints,
56
+ and ends up back at the start pose:
57
+
58
+ # translations:
59
+ 1. Translate in tool +X by a set amount, then -X by the same amount (= return to origin)
60
+ 2. Similar for tool +/- Y
61
+ 3. Similar for tool +/- Z
62
+ # single rotations:
63
+ 4. Rotate around tool +X by a set amount, then -X (= return to origin)
64
+ 5. Similar for tool +/- Y
65
+ 6. Similar for tool +/- Z
66
+ 7. Rotate around the tool XY diagonal, then return
67
+ 8. Similar for the YZ diagonal
68
+ 9. Similar for the XZ diagonal
69
+ # chained rotations:
70
+ 10. Rotate around tool Z, then Y, then X; then return in the reverse order.
71
+
72
+ See --help for config options (e.g. range of motion, speed, including/excluding some of the motions)
64
73
 
65
74
  positional arguments:
66
75
  path Path to the robot implementation
67
76
 
68
- optional arguments:
77
+ options:
69
78
  -h, --help show this help message and exit
70
79
  -m MODEL, --model MODEL
71
80
  Name of the robot model as defined in the implementation.
72
- -sl SPEED_LINEAR, --speed-linear SPEED_LINEAR
73
- Linear end-effector speed, meters per second.
74
- Default: 0.05, Max: 0.1
75
- -sa SPEED_ANGULAR, --speed-angular SPEED_ANGULAR
76
- Angular end-effector speed, radians per second.
77
- Default: 0.2617993877991494, Max: 0.6981317007977318
78
- -d DIMENSION, --dimension DIMENSION
79
- Number of axes to move the robot in.
80
- Default: 1
81
- -l LENGTH, --length LENGTH
82
- Length of test movement, meters.
83
- Default:0.05, Max: 0.1m
84
81
  -ip IP_ADDRESS, --ip-address IP_ADDRESS
85
82
  IP address of the robot.
86
83
  Default: 192.168.100.100
84
+ -sl SPEED_LINEAR, --speed-linear SPEED_LINEAR
85
+ Linear end-effector speed, meters per second.
86
+ Default: 0.05
87
+ -sa SPEED_ROTATION, --speed-rotation SPEED_ROTATION
88
+ Rotational end-effector speed, degrees per second.
89
+ Default: 5.0°
90
+ --test [{translations,single-rotations,chained-rotations} ...]
91
+ Select which tests to run, can specify one or multiple.
92
+ Choices: translations, single-rotations, chained-rotations.
93
+ Default: run all.
94
+ --max-distance-translation MAX_DISTANCE_TRANSLATION
95
+ Maximum distance for translational movements, meters.
96
+ Default: 0.05
97
+ --max-distance-degrees MAX_DISTANCE_DEGREES
98
+ Maximum distance for rotational movements, degrees.
99
+ Default: 10.0°
87
100
  -tl TOLERANCE_LINEAR, --tolerance-linear TOLERANCE_LINEAR
88
- Linear tolerance of the end-effector position achieved by robot.
89
- Default: 0.001 meters
90
- -ta TOLERANCE_ANGULAR, --tolerance-angular TOLERANCE_ANGULAR
91
- Angular tolerance of the end-effector position achieved by robot.
92
- Default: 0.01 radians
101
+ Consider a position linearly reached when within this distance, meters
102
+ Default: 0.001m
103
+ -ta TOLERANCE_ROTATION, --tolerance-rotation TOLERANCE_ROTATION
104
+ Consider a position rotationally reached when within this distance, degrees
105
+ Default: 0.
93
106
  -v, --verbose Enable debug logging.
107
+ -d DIMENSION, --dimension DIMENSION
108
+ OBSOLETE: See --test
109
+ -l LENGTH, --length LENGTH
110
+ OBSOLETE: See --max-distance-translation and --max-distance-degrees
94
111
 
95
- Usage example: mirai-sandbox ./examples/cartesian_velocity_robot.py
112
+ Usage example: mirai-sandbox ../examples/cartesian_velocity_robot.py
96
113
  ```
114
+
97
115
  ## Mirai dev server
98
116
  This tool simulates a mirai controller in certain (very simplified) ways.
99
117
  Once started, it listens on port 6599 for the commands sent by either your PLC or robot program,
@@ -158,4 +176,4 @@ optional arguments:
158
176
 
159
177
  Usage example:
160
178
  # mirai-dev-client GetBoxMetadata
161
- ```
179
+ ```
@@ -1,7 +1,7 @@
1
1
  import logging
2
- from typing import Optional
3
2
 
4
3
  import numpy as np
4
+ from scipy.spatial.transform import Rotation
5
5
 
6
6
  from micropsi_integration_sdk import CartesianPoseRobot, HardwareState
7
7
 
@@ -14,20 +14,20 @@ class MyCartesianPoseRobot(CartesianPoseRobot):
14
14
  self.__connected = False
15
15
  self.__ready_for_control = False
16
16
  self.__controlled = False
17
- self.__joint_positions = np.zeros(3)
17
+ self.__pose = np.eye(4)
18
18
 
19
19
  @staticmethod
20
20
  def get_supported_models() -> list:
21
21
  return ["MyRobot Cartesian Pose"]
22
22
 
23
23
  def get_joint_count(self) -> int:
24
- return 3
24
+ return 6
25
25
 
26
- def get_joint_speed_limits(self) -> np.array:
27
- return np.array([.2, .2, .2])
26
+ def get_joint_speed_limits(self) -> np.ndarray:
27
+ return np.ones(6)
28
28
 
29
- def get_joint_position_limits(self) -> np.array:
30
- return np.array([[-.5, .5], [-.5, .5], [-.5, .5]])
29
+ def get_joint_position_limits(self) -> np.ndarray:
30
+ return np.array([[-1, 1]] * 6)
31
31
 
32
32
  def connect(self) -> bool:
33
33
  self.__connected = True
@@ -49,9 +49,10 @@ class MyCartesianPoseRobot(CartesianPoseRobot):
49
49
  self.__controlled = False
50
50
  self.__ready_for_control = False
51
51
 
52
- def get_hardware_state(self) -> Optional[HardwareState]:
52
+ def get_hardware_state(self) -> HardwareState:
53
53
  state = HardwareState(
54
- joint_positions=np.copy(self.__joint_positions),
54
+ joint_positions=self.inverse_kinematics(end_effector_pose=self.__pose),
55
+ end_effector_pose=np.copy(self.__pose),
55
56
  )
56
57
  LOG.debug("State: %s", state)
57
58
  return state
@@ -59,25 +60,36 @@ class MyCartesianPoseRobot(CartesianPoseRobot):
59
60
  def clear_cached_hardware_state(self) -> None:
60
61
  pass
61
62
 
62
- def forward_kinematics(self, *, joint_positions: np.array) -> np.array:
63
- matrix = np.identity(4)
64
- matrix[:3, 3] = joint_positions
65
- return matrix
63
+ def forward_kinematics(self, *, joint_positions: np.ndarray) -> np.ndarray:
64
+ # trivial mock kinematics
65
+ pose = np.eye(4)
66
+ pose[:3, 3] = joint_positions[:3]
67
+ pose[:3, :3] = Rotation.from_rotvec(joint_positions[3:6]).as_matrix()
68
+ return pose
69
+
70
+ def inverse_kinematics(self, *, end_effector_pose: np.ndarray,
71
+ joint_reference=None) -> np.ndarray:
72
+ # trivial mock kinematics
73
+ position = end_effector_pose[:3, 3]
74
+ axis_angle = Rotation.from_matrix(end_effector_pose[:3, :3]).as_rotvec()
75
+ return np.concatenate([position, axis_angle])
66
76
 
67
77
  def send_goal_pose(self, *, goal_pose: np.ndarray, step_count: int) -> None:
68
78
  assert goal_pose.shape == (4, 4)
69
- self.__joint_positions = goal_pose[:3, 3]
79
+ self.__pose = np.copy(goal_pose)
70
80
 
71
81
  def are_joint_positions_safe(self, *, joint_positions: np.ndarray) -> bool:
72
82
  limits = self.get_joint_position_limits()
73
- for idx, joint_position in enumerate(joint_positions):
74
- limit = limits[idx]
75
- if not limit[0] < joint_position < limit[1]:
83
+ for idx, position in enumerate(joint_positions):
84
+ if not limits[idx][0] <= position <= limits[idx][1]:
76
85
  return False
77
86
  return True
78
87
 
79
- def command_move(self, *, joint_positions: np.array) -> None:
80
- self.__joint_positions = np.copy(joint_positions)
88
+ def command_move(self, *, joint_positions: np.ndarray) -> None:
89
+ self.__pose = self.forward_kinematics(joint_positions=joint_positions)
81
90
 
82
91
  def command_stop(self) -> None:
83
92
  pass
93
+
94
+ def get_slowdown_steps_in_seconds(self) -> float:
95
+ return 0.05
@@ -0,0 +1,98 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ from scipy.spatial.transform import Rotation
5
+
6
+ from micropsi_integration_sdk import CartesianVelocityRobot, HardwareState
7
+
8
+ LOG = logging.getLogger(__name__)
9
+
10
+
11
+ class MyCartesianVelocityRobot(CartesianVelocityRobot):
12
+ def __init__(self, **kwargs):
13
+ super().__init__(**kwargs)
14
+ self.__connected = False
15
+ self.__ready_for_control = False
16
+ self.__controlled = False
17
+ self.__pose = np.eye(4)
18
+
19
+ @staticmethod
20
+ def get_supported_models() -> list:
21
+ return ["MyRobot Cartesian Velocity"]
22
+
23
+ def get_joint_count(self) -> int:
24
+ return 6
25
+
26
+ def get_joint_speed_limits(self) -> np.ndarray:
27
+ return np.ones(6)
28
+
29
+ def get_joint_position_limits(self) -> np.ndarray:
30
+ return np.array([[-1, 1]] * 6)
31
+
32
+ def connect(self) -> bool:
33
+ self.__connected = True
34
+ return True
35
+
36
+ def disconnect(self) -> None:
37
+ self.__connected = False
38
+
39
+ def prepare_for_control(self) -> None:
40
+ self.__ready_for_control = True
41
+
42
+ def is_ready_for_control(self) -> bool:
43
+ return self.__ready_for_control
44
+
45
+ def take_control(self) -> None:
46
+ self.__controlled = True
47
+
48
+ def release_control(self) -> None:
49
+ self.__controlled = False
50
+ self.__ready_for_control = False
51
+
52
+ def get_hardware_state(self) -> HardwareState:
53
+ state = HardwareState(
54
+ joint_positions=self.inverse_kinematics(end_effector_pose=self.__pose),
55
+ end_effector_pose=np.copy(self.__pose),
56
+ )
57
+ LOG.debug("State: %s", state)
58
+ return state
59
+
60
+ def clear_cached_hardware_state(self) -> None:
61
+ pass
62
+
63
+ def forward_kinematics(self, *, joint_positions: np.ndarray) -> np.ndarray:
64
+ # trivial mock kinematics
65
+ pose = np.eye(4)
66
+ pose[:3, 3] = joint_positions[:3]
67
+ pose[:3, :3] = Rotation.from_rotvec(joint_positions[3:6]).as_matrix()
68
+ return pose
69
+
70
+ def inverse_kinematics(self, *, end_effector_pose: np.ndarray,
71
+ joint_reference=None) -> np.ndarray:
72
+ # trivial mock kinematics
73
+ position = end_effector_pose[:3, 3]
74
+ axis_angle = Rotation.from_matrix(end_effector_pose[:3, :3]).as_rotvec()
75
+ return np.concatenate([position, axis_angle])
76
+
77
+ def send_velocity(self, *, velocity: np.ndarray, step_count: int) -> None:
78
+ assert velocity.shape == (6,), velocity.shape
79
+ dt = 1.0 / self.get_frequency()
80
+ self.__pose[:3, 3] += velocity[:3] * dt
81
+ delta_R = Rotation.from_rotvec(velocity[3:6] * dt).as_matrix()
82
+ self.__pose[:3, :3] = delta_R @ self.__pose[:3, :3]
83
+
84
+ def are_joint_positions_safe(self, *, joint_positions: np.ndarray) -> bool:
85
+ limits = self.get_joint_position_limits()
86
+ for idx, position in enumerate(joint_positions):
87
+ if not limits[idx][0] <= position <= limits[idx][1]:
88
+ return False
89
+ return True
90
+
91
+ def command_move(self, *, joint_positions: np.ndarray) -> None:
92
+ self.__pose = self.forward_kinematics(joint_positions=joint_positions)
93
+
94
+ def command_stop(self) -> None:
95
+ pass
96
+
97
+ def get_slowdown_steps_in_seconds(self) -> float:
98
+ return 0.05
@@ -1,7 +1,7 @@
1
1
  import logging
2
- from typing import Optional
3
2
 
4
3
  import numpy as np
4
+ from scipy.spatial.transform import Rotation
5
5
 
6
6
  from micropsi_integration_sdk import JointPositionRobot, HardwareState
7
7
 
@@ -11,23 +11,23 @@ LOG = logging.getLogger(__name__)
11
11
  class MyJointPositionRobot(JointPositionRobot):
12
12
  def __init__(self, **kwargs):
13
13
  super().__init__(**kwargs)
14
- self.__joint_positions = np.zeros(3)
15
14
  self.__connected = False
16
15
  self.__ready_for_control = False
17
16
  self.__controlled = False
17
+ self.__pose = np.eye(4)
18
18
 
19
19
  @staticmethod
20
20
  def get_supported_models() -> list:
21
21
  return ["MyRobot JointPosition"]
22
22
 
23
23
  def get_joint_count(self) -> int:
24
- return 3
24
+ return 6
25
25
 
26
- def get_joint_speed_limits(self) -> np.array:
27
- return np.array([.2, .2, .2])
26
+ def get_joint_speed_limits(self) -> np.ndarray:
27
+ return np.ones(6)
28
28
 
29
- def get_joint_position_limits(self) -> np.array:
30
- return np.array([[-.5, .5], [-.5, .5], [-.5, .5]])
29
+ def get_joint_position_limits(self) -> np.ndarray:
30
+ return np.array([[-1, 1]] * 6)
31
31
 
32
32
  def connect(self) -> bool:
33
33
  self.__connected = True
@@ -49,9 +49,10 @@ class MyJointPositionRobot(JointPositionRobot):
49
49
  self.__controlled = False
50
50
  self.__ready_for_control = False
51
51
 
52
- def get_hardware_state(self) -> Optional[HardwareState]:
52
+ def get_hardware_state(self) -> HardwareState:
53
53
  state = HardwareState(
54
- joint_positions=np.copy(self.__joint_positions),
54
+ joint_positions=self.inverse_kinematics(end_effector_pose=self.__pose),
55
+ end_effector_pose=np.copy(self.__pose),
55
56
  )
56
57
  LOG.debug("State: %s", state)
57
58
  return state
@@ -59,27 +60,35 @@ class MyJointPositionRobot(JointPositionRobot):
59
60
  def clear_cached_hardware_state(self) -> None:
60
61
  pass
61
62
 
62
- def forward_kinematics(self, *, joint_positions: np.array) -> np.array:
63
- matrix = np.identity(4)
64
- matrix[:3, 3] = joint_positions
65
- return matrix
63
+ def forward_kinematics(self, *, joint_positions: np.ndarray) -> np.ndarray:
64
+ # trivial mock kinematics
65
+ pose = np.eye(4)
66
+ pose[:3, 3] = joint_positions[:3]
67
+ pose[:3, :3] = Rotation.from_rotvec(joint_positions[3:6]).as_matrix()
68
+ return pose
66
69
 
67
70
  def inverse_kinematics(self, *, end_effector_pose: np.ndarray,
68
- joint_reference: Optional[np.ndarray]) -> Optional[np.ndarray]:
69
- return end_effector_pose[:3, 3]
71
+ joint_reference=None) -> np.ndarray:
72
+ # trivial mock kinematics
73
+ position = end_effector_pose[:3, 3]
74
+ axis_angle = Rotation.from_matrix(end_effector_pose[:3, :3]).as_rotvec()
75
+ return np.concatenate([position, axis_angle])
70
76
 
71
77
  def are_joint_positions_safe(self, *, joint_positions: np.ndarray) -> bool:
72
78
  limits = self.get_joint_position_limits()
73
79
  for idx, position in enumerate(joint_positions):
74
- if not limits[idx][0] < position < limits[idx][1]:
80
+ if not limits[idx][0] <= position <= limits[idx][1]:
75
81
  return False
76
82
  return True
77
83
 
78
84
  def send_joint_positions(self, *, joint_positions: np.ndarray, step_count: int) -> None:
79
- self.__joint_positions = np.copy(joint_positions)
85
+ self.__pose = self.forward_kinematics(joint_positions=joint_positions)
80
86
 
81
- def command_move(self, *, joint_positions: np.array) -> None:
82
- self.__joint_positions = np.copy(joint_positions)
87
+ def command_move(self, *, joint_positions: np.ndarray) -> None:
88
+ self.__pose = self.forward_kinematics(joint_positions=joint_positions)
83
89
 
84
90
  def command_stop(self) -> None:
85
91
  pass
92
+
93
+ def get_slowdown_steps_in_seconds(self) -> float:
94
+ return 0.05