Skip to content

Commit fc76a83

Browse files
committed
install instruction for compatible sensapex umsdk 1.22 version
1 parent 69dc924 commit fc76a83

File tree

5 files changed

+243
-4
lines changed

5 files changed

+243
-4
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,15 @@ Please see the [contribution guidelines](https://github.com/larsrollik/templatep
135135

136136
## License
137137
This software is released under the **[BSD 3-Clause License](https://github.com/larsrollik/templatepy/blob/main/LICENSE)**
138+
139+
140+
```shell
141+
wget -q -O tmp.zip http://dist.sensapex.com/misc/um-sdk/latest/umsdk-1_022-src.zip \
142+
&& unzip tmp.zip \
143+
&& rm tmp.zip \
144+
&& cd umsdk-1_022/src/lib/ \
145+
&& make -f Makefile.linux
146+
147+
sudo make -f Makefile.linux install
148+
echo $PWD
149+
```

sensapex-api/manipulator.py

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# API wrapper for Sensapex manipulator
2+
import logging
3+
4+
import numpy as np
5+
from sensapex import UMP
6+
7+
8+
def get_device_list(library_path: str = None):
9+
""""""
10+
UMP.set_library_path(library_path)
11+
ump = UMP.get_ump()
12+
return ump.list_devices()
13+
14+
15+
def get_device_by_id(device_id=None, library_path: str = None):
16+
""""""
17+
UMP.set_library_path(library_path)
18+
ump = UMP.get_ump()
19+
return ump.get_device(device_id)
20+
21+
22+
class SensapexManipulator:
23+
"""
24+
25+
device methods for manipulators:
26+
dev_id
27+
get_pos
28+
goto_pos
29+
is_busy
30+
n_axes
31+
32+
stop
33+
34+
methods on device.ump object
35+
36+
broadcast_address
37+
calibrate_zero_position
38+
39+
manipulator.ump.get_firmware_version
40+
41+
"""
42+
43+
id = None
44+
device = None
45+
library_path = None
46+
47+
default_move_speed = None
48+
49+
_position = None
50+
_relative_zero = None
51+
52+
def __init__(
53+
self,
54+
device_id: int = None,
55+
library_path: str = "/usr/lib",
56+
default_move_speed: int = 5,
57+
):
58+
super(SensapexManipulator, self).__init__()
59+
logging.debug(
60+
f"Initialising SensapexManipulator object for device={device_id}. "
61+
f"Library: '{library_path}'. default_move_speed={default_move_speed}"
62+
)
63+
self.id = device_id
64+
self.library_path = library_path
65+
self.device = get_device_by_id(
66+
device_id=self.id, library_path=self.library_path
67+
)
68+
69+
assert 1 <= default_move_speed < np.inf
70+
self.default_move_speed = default_move_speed
71+
72+
@property
73+
def is_busy(self):
74+
return self.device.is_busy()
75+
76+
@property
77+
def position(self):
78+
"""Get position of all axes"""
79+
current_position = self.device.get_pos()
80+
logging.debug(f"Current position reading: {current_position}")
81+
return np.asarray(current_position)
82+
83+
@property
84+
def relative_zero(self):
85+
"""Get relative position of all axes"""
86+
if self._relative_zero is None:
87+
logging.debug("No relative zero set")
88+
return None
89+
90+
relative_zero = self.position - self._relative_zero
91+
logging.debug(f"Relative zero: {relative_zero.tolist()}")
92+
return relative_zero
93+
94+
@relative_zero.setter
95+
def relative_zero(self, pos):
96+
"""Get current position relative to relative origin"""
97+
pos = np.asarray(pos)
98+
curr_zero = (
99+
self._relative_zero.tolist()
100+
if self._relative_zero is not None
101+
else self._relative_zero
102+
)
103+
logging.debug(f"Setting relative zero from->to: {curr_zero} -> {pos.tolist()}")
104+
self._relative_zero = pos
105+
106+
def set_relative_zero_all(self):
107+
"""Set current position to new relative zero position on ALL axes"""
108+
logging.debug("Requested relative zero for all axes")
109+
self.relative_zero = self.position
110+
111+
def set_relative_zero_axis(self, axis: int = None):
112+
"""Set current position to new relative zero position on SPECICIEF axis"""
113+
logging.debug(f"Requested relative zero for axis: {axis}")
114+
if self.relative_zero is None:
115+
self.relative_zero = self.position
116+
self._relative_zero[axis] = self.position[axis]
117+
118+
def get_device_state(self):
119+
"""Get device metadata as dictionary"""
120+
if self.device is None:
121+
return {}
122+
123+
state = {
124+
"device_id": self.device.dev_id,
125+
"is_busy": self.device.is_busy(),
126+
"n_axes": self.device.n_axes(),
127+
"position": self.position.tolist(),
128+
"relative_position": self.relative_zero.tolist(),
129+
"broadcast_address": self.device.ump.broadcast_address,
130+
"firmware_version": self.device.ump.get_firmware_version(self.id),
131+
}
132+
logging.debug(state)
133+
return state
134+
135+
def set_position(
136+
self,
137+
position=None,
138+
speed: int = None,
139+
simultaneous=False,
140+
linear=False,
141+
max_acceleration=0,
142+
):
143+
"""Set absolute position of all axes
144+
145+
:param position: [x, y, z, w] target position list, in um
146+
:param speed: speed, in um/s
147+
:param simultaneous: move all axes simultaneously
148+
:param linear: if simultaneous movement, then setting same speed value on all axes, otherwise distance-dependent
149+
:param max_acceleration: in um/(s**2), default=0 will be evaluated to default in ump object
150+
:return:
151+
"""
152+
if position is None:
153+
return
154+
155+
if speed is None:
156+
speed = self.default_move_speed
157+
158+
# https://github.com/sensapex/sensapex-py/blob/bc715130ca1c64dfcaa6a93ce0d5c31bdadd732a/sensapex/sensapex.py#L166
159+
assert len(position) == self.device.n_axes()
160+
# https://github.com/sensapex/sensapex-py/blob/bc715130ca1c64dfcaa6a93ce0d5c31bdadd732a/sensapex/sensapex.py#L165
161+
assert speed >= 1
162+
163+
self.device.goto_pos(
164+
position,
165+
speed,
166+
simultaneous=simultaneous,
167+
linear=linear,
168+
max_acceleration=max_acceleration,
169+
)
170+
171+
def get_axis_position(self, axis: int = None):
172+
"""Get position of specified axis
173+
174+
:param axis: int
175+
:return: list of position floats
176+
"""
177+
current_axis_position = self.position[axis]
178+
logging.debug(f"Axis {axis} position: {current_axis_position}")
179+
return current_axis_position
180+
181+
def set_axis_position(
182+
self,
183+
axis: int = None,
184+
position: float = None,
185+
speed: int = None,
186+
**kwargs,
187+
):
188+
"""Set position of specified axis"""
189+
new_position = self.position
190+
new_position[axis] = position
191+
self.set_position(new_position, speed=speed, **kwargs)
192+
193+
def set_axis_position_relative(
194+
self,
195+
axis: int = None,
196+
distance: float = None,
197+
speed: int = None,
198+
**kwargs,
199+
):
200+
"""Move axis by specified relative distance from current position"""
201+
current_axis_position = self.get_axis_position(axis=axis)
202+
new_axis_position = current_axis_position + distance
203+
204+
logging.debug(
205+
f"Requested move on axis={axis} by {distance}µm at {speed}µm/s. kwargs: {kwargs}"
206+
)
207+
208+
self.set_axis_position(
209+
axis=axis, position=new_axis_position, speed=speed, **kwargs
210+
)
211+
212+
213+
"""
214+
import logging
215+
logging.getLogger().setLevel("DEBUG")
216+
217+
def print_positions(s):
218+
print("origin ", s._relative_zero)
219+
print("position", s.position)
220+
print("relative", s.relative_zero)
221+
222+
s = SensapexManipulator(device_id=1)
223+
s.set_relative_zero_axis(-1)
224+
225+
# s.set_relative_zero_all()
226+
227+
print_positions(s)
228+
s.set_axis_position_relative(-1, -2000, 500)
229+
print_positions(s)
230+
231+
"""

templatepy/example.data.file.config

Lines changed: 0 additions & 2 deletions
This file was deleted.

templatepy/example.data.file.test-extension-yu48

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)