moteus 0.3.67__py3-none-any.whl → 0.3.69__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.
- moteus/moteus.py +22 -14
- moteus/moteus_tool.py +40 -20
- moteus/version.py +1 -1
- {moteus-0.3.67.dist-info → moteus-0.3.69.dist-info}/METADATA +1 -1
- {moteus-0.3.67.dist-info → moteus-0.3.69.dist-info}/RECORD +8 -8
- {moteus-0.3.67.dist-info → moteus-0.3.69.dist-info}/WHEEL +0 -0
- {moteus-0.3.67.dist-info → moteus-0.3.69.dist-info}/entry_points.txt +0 -0
- {moteus-0.3.67.dist-info → moteus-0.3.69.dist-info}/top_level.txt +0 -0
moteus/moteus.py
CHANGED
@@ -619,6 +619,12 @@ class Controller:
|
|
619
619
|
self.transport = get_singleton_transport()
|
620
620
|
return self.transport
|
621
621
|
|
622
|
+
async def flush_transport(self):
|
623
|
+
try:
|
624
|
+
await asyncio.wait_for(self.transport.read(), 0.02)
|
625
|
+
except asyncio.TimeoutError:
|
626
|
+
pass
|
627
|
+
|
622
628
|
def _make_query_data(self, query_resolution=None):
|
623
629
|
if query_resolution is None:
|
624
630
|
query_resolution = self.query_resolution
|
@@ -761,7 +767,7 @@ class Controller:
|
|
761
767
|
async def set_stop(self, *args, **kwargs):
|
762
768
|
return await self.execute(self.make_stop(**kwargs))
|
763
769
|
|
764
|
-
def make_set_output(self,
|
770
|
+
def make_set_output(self, *args,
|
765
771
|
position=0.0,
|
766
772
|
query=False,
|
767
773
|
query_override=None,
|
@@ -770,6 +776,9 @@ class Controller:
|
|
770
776
|
"""Return a moteus.Command structure with data necessary to send a
|
771
777
|
set output nearest command."""
|
772
778
|
|
779
|
+
if len(args):
|
780
|
+
raise ValueError(f'unexpected positional arguments: {args}')
|
781
|
+
|
773
782
|
result = self._make_command(
|
774
783
|
query=query, query_override=query_override)
|
775
784
|
|
@@ -784,39 +793,42 @@ class Controller:
|
|
784
793
|
result.data = data_buf.getvalue()
|
785
794
|
return result
|
786
795
|
|
787
|
-
def make_set_output_nearest(self,
|
796
|
+
def make_set_output_nearest(self, *args,
|
788
797
|
position=0.0,
|
789
798
|
query=False,
|
790
799
|
query_override=None):
|
791
800
|
return self.make_set_output(
|
801
|
+
*args,
|
792
802
|
position=position, query=query, query_override=query_override,
|
793
803
|
cmd=Register.SET_OUTPUT_NEAREST)
|
794
804
|
|
795
|
-
def make_set_output_exact(self,
|
805
|
+
def make_set_output_exact(self, *args,
|
796
806
|
position=0.0,
|
797
807
|
query=False,
|
798
808
|
query_override=None):
|
799
809
|
return self.make_set_output(
|
810
|
+
*args,
|
800
811
|
position=position, query=query, query_override=query_override,
|
801
812
|
cmd=Register.SET_OUTPUT_EXACT)
|
802
813
|
|
803
814
|
async def set_output(self, *args, cmd=None, **kwargs):
|
804
|
-
return await self.execute(self.make_set_output(**kwargs, cmd=cmd))
|
815
|
+
return await self.execute(self.make_set_output(*args, **kwargs, cmd=cmd))
|
805
816
|
|
806
817
|
async def set_output_nearest(self, *args, **kwargs):
|
807
|
-
return await self.set_output(cmd=Register.SET_OUTPUT_NEAREST, **kwargs)
|
818
|
+
return await self.set_output(*args, cmd=Register.SET_OUTPUT_NEAREST, **kwargs)
|
808
819
|
|
809
820
|
async def set_output_exact(self, *args, **kwargs):
|
810
|
-
return await self.set_output(cmd=Register.SET_OUTPUT_EXACT, **kwargs)
|
821
|
+
return await self.set_output(*args, cmd=Register.SET_OUTPUT_EXACT, **kwargs)
|
811
822
|
|
812
823
|
|
813
824
|
# For backwards compatibility, "*_output_nearest" used to be named
|
814
825
|
# "make/set_rezero".
|
815
|
-
def make_rezero(self,
|
826
|
+
def make_rezero(self, *args,
|
816
827
|
rezero=0.0,
|
817
828
|
query=False,
|
818
829
|
query_override=None):
|
819
830
|
return self.make_set_output(
|
831
|
+
*args,
|
820
832
|
position=rezero, query=query, query_override=query_override,
|
821
833
|
cmd=Register.SET_OUTPUT_NEAREST)
|
822
834
|
|
@@ -1176,8 +1188,8 @@ class Controller:
|
|
1176
1188
|
|
1177
1189
|
combiner = mp.WriteCombiner(
|
1178
1190
|
writer, 0x00, int(Register.AUX1_GPIO_COMMAND), [
|
1179
|
-
mp.INT8 if aux1 else mp.IGNORE,
|
1180
|
-
mp.INT8 if aux2 else mp.IGNORE,
|
1191
|
+
mp.INT8 if aux1 is not None else mp.IGNORE,
|
1192
|
+
mp.INT8 if aux2 is not None else mp.IGNORE,
|
1181
1193
|
])
|
1182
1194
|
|
1183
1195
|
if combiner.maybe_write():
|
@@ -1355,11 +1367,7 @@ class Stream:
|
|
1355
1367
|
self._read_data = b''
|
1356
1368
|
|
1357
1369
|
# Now flush anything from the underlying transport if applicable.
|
1358
|
-
|
1359
|
-
await asyncio.wait_for(self.controller._get_transport().read(), 0.02)
|
1360
|
-
except asyncio.TimeoutError:
|
1361
|
-
# This is the expected path.
|
1362
|
-
pass
|
1370
|
+
await self.controller.flush_transport()
|
1363
1371
|
|
1364
1372
|
async def _read_maybe_empty_line(self):
|
1365
1373
|
while b'\n' not in self._read_data and b'\r' not in self._read_data:
|
moteus/moteus_tool.py
CHANGED
@@ -305,6 +305,10 @@ def _round_nearest_4v(input_V):
|
|
305
305
|
return round(input_V / 4) * 4
|
306
306
|
|
307
307
|
|
308
|
+
def _average(x):
|
309
|
+
return sum(x) / len(x)
|
310
|
+
|
311
|
+
|
308
312
|
def expand_targets(targets):
|
309
313
|
result = set()
|
310
314
|
|
@@ -951,16 +955,12 @@ class Stream:
|
|
951
955
|
if encoder_type == 4: # hall
|
952
956
|
hall_configured = True
|
953
957
|
|
954
|
-
if self.args.cal_hall:
|
958
|
+
if self.args.cal_hall or hall_configured:
|
955
959
|
if not hall_configured:
|
956
960
|
raise RuntimeError("--cal-hall specified, but hall sensors " +
|
957
961
|
"not configured on device")
|
958
962
|
return await self.calibrate_encoder_mapping_hall(encoder_cal_voltage)
|
959
963
|
else:
|
960
|
-
if hall_configured:
|
961
|
-
raise RuntimeError(
|
962
|
-
"Cannot perform encoder mapping with hall sensors, " +
|
963
|
-
"use --cal-hall")
|
964
964
|
try:
|
965
965
|
return await self.calibrate_encoder_mapping_absolute(encoder_cal_voltage)
|
966
966
|
except:
|
@@ -1243,6 +1243,16 @@ class Stream:
|
|
1243
1243
|
desired_encoder_bw_hz = min(
|
1244
1244
|
desired_encoder_bw_hz, 2e-2 / inductance)
|
1245
1245
|
|
1246
|
+
# Also, limit the bandwidth for halls based on the number
|
1247
|
+
# of poles and the estimated calibration speed.
|
1248
|
+
if hall_output:
|
1249
|
+
max_pole_bandwidth_hz = (
|
1250
|
+
0.5 * self.args.cal_motor_poles *
|
1251
|
+
self.args.cal_motor_speed)
|
1252
|
+
desired_encoder_bw_hz = min(
|
1253
|
+
desired_encoder_bw_hz, max_pole_bandwidth_hz)
|
1254
|
+
|
1255
|
+
|
1246
1256
|
# And our bandwidth with the filter can be no larger than
|
1247
1257
|
# 1/30th the control rate.
|
1248
1258
|
encoder_bw_hz = min(control_rate_hz / 30, desired_encoder_bw_hz)
|
@@ -1312,32 +1322,42 @@ class Stream:
|
|
1312
1322
|
|
1313
1323
|
start_time = time.time()
|
1314
1324
|
|
1325
|
+
SAMPLE_PERIOD_S = 0.02
|
1326
|
+
AVERAGE_PERIOD_S = 0.10
|
1327
|
+
|
1328
|
+
AVERAGE_COUNT = int(AVERAGE_PERIOD_S / SAMPLE_PERIOD_S)
|
1329
|
+
|
1315
1330
|
def sign(x):
|
1316
1331
|
return 1 if x >= 0 else -1
|
1317
1332
|
|
1318
|
-
|
1319
|
-
|
1333
|
+
velocity_samples = []
|
1334
|
+
|
1320
1335
|
while True:
|
1321
1336
|
data = await self.read_servo_stats()
|
1322
|
-
|
1337
|
+
velocity_samples.append(data.velocity)
|
1338
|
+
|
1339
|
+
if len(velocity_samples) > (3 * AVERAGE_COUNT):
|
1340
|
+
del velocity_samples[0]
|
1341
|
+
|
1342
|
+
recent_average = _average(velocity_samples[-AVERAGE_COUNT:])
|
1323
1343
|
|
1324
|
-
# As a fallback, timeout after
|
1344
|
+
# As a fallback, timeout after a fixed amount of waiting.
|
1325
1345
|
if (time.time() - start_time) > 2.0:
|
1326
|
-
return
|
1346
|
+
return recent_average
|
1327
1347
|
|
1328
|
-
if
|
1329
|
-
|
1348
|
+
if (len(velocity_samples) >= AVERAGE_COUNT and
|
1349
|
+
abs(recent_average) < 0.2):
|
1350
|
+
return recent_average
|
1330
1351
|
|
1331
|
-
if
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
return velocity
|
1336
|
-
old_change = change
|
1352
|
+
if len(velocity_samples) == 3 * AVERAGE_COUNT:
|
1353
|
+
average_1 = _average(velocity_samples[:AVERAGE_COUNT])
|
1354
|
+
average_2 = _average(velocity_samples[AVERAGE_COUNT:2*AVERAGE_COUNT])
|
1355
|
+
average_3 = recent_average
|
1337
1356
|
|
1338
|
-
|
1357
|
+
if sign(average_3 - average_2) != sign(average_2 - average_1):
|
1358
|
+
return recent_average
|
1339
1359
|
|
1340
|
-
await asyncio.sleep(
|
1360
|
+
await asyncio.sleep(SAMPLE_PERIOD_S)
|
1341
1361
|
|
1342
1362
|
return velocity
|
1343
1363
|
|
moteus/version.py
CHANGED
@@ -5,8 +5,8 @@ moteus/calibrate_encoder.py,sha256=R3pRgGqrDCcmKQqFE7Fr4p8TSie179iqNfBwEJS3pL0,1
|
|
5
5
|
moteus/command.py,sha256=UkOsbtkso6Oyex8CfbpAKpBNriik519ymxL86EZGkRs,1169
|
6
6
|
moteus/export.py,sha256=vRIfldaqz1eHtWo3993SvatATtu73TZbejL0hzQe8YE,1646
|
7
7
|
moteus/fdcanusb.py,sha256=7PrQiCTROY96gdT2zSZYU1bOCriw-I7H6NspaZpiEx4,7431
|
8
|
-
moteus/moteus.py,sha256=
|
9
|
-
moteus/moteus_tool.py,sha256=
|
8
|
+
moteus/moteus.py,sha256=2x5i-4BpTwS3Uo9FWyWesR--acIO8TJb0wCQHbuKuxQ,48131
|
9
|
+
moteus/moteus_tool.py,sha256=ccrvAVdxRZEnheALvAgbR7mDrlU90Ses3kj1kfEsVfI,70167
|
10
10
|
moteus/multiplex.py,sha256=LF6MuelzYHqqsCJuCB9YeEyUA03eBaTYRwAVotX3qm8,10120
|
11
11
|
moteus/posix_aioserial.py,sha256=2oDrw8TBEwuEQjY41g9rHeuFeffcPHqMwNS3nf5NVq8,3137
|
12
12
|
moteus/pythoncan.py,sha256=ofotOrDuaFhTLvaokaO3EJK6quVc75Bq-ue70lDMtXI,4071
|
@@ -14,10 +14,10 @@ moteus/reader.py,sha256=9i1-h4aGd4syfqtWJcpg70Bl-bmunkGU4FmXmOLyRt8,12121
|
|
14
14
|
moteus/regression.py,sha256=M5gjDBYJQ64iBXIrvBhMkD8TYhtlnQ85x8U4py0niGA,1196
|
15
15
|
moteus/router.py,sha256=501W5GZ12rFoc1lmcH3S7IYsoc-Q_-FJ4B3i37RzE3Q,2061
|
16
16
|
moteus/transport.py,sha256=WhkW2G9i25lkOlO55eI5_oXmU0PhDmxTeJ75Sg_7nTI,1021
|
17
|
-
moteus/version.py,sha256=
|
17
|
+
moteus/version.py,sha256=FEYQhXwueAJ_XxxIiWQCnSdWVFCa2egsxksGzbElp7g,627
|
18
18
|
moteus/win32_aioserial.py,sha256=culdl-vYxBKD5n2s5LkIMGyUaHyCcEc8BL5-DWEaxX8,2025
|
19
|
-
moteus-0.3.
|
20
|
-
moteus-0.3.
|
21
|
-
moteus-0.3.
|
22
|
-
moteus-0.3.
|
23
|
-
moteus-0.3.
|
19
|
+
moteus-0.3.69.dist-info/METADATA,sha256=TRwp5Wf0k3CPaiHBxmpm-URMuJ2lL5wlTWErGm6eXjg,3372
|
20
|
+
moteus-0.3.69.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
21
|
+
moteus-0.3.69.dist-info/entry_points.txt,sha256=accRcwir_K8wCf7i3qHb5R6CPh5SiSgd5a1A92ibb9E,56
|
22
|
+
moteus-0.3.69.dist-info/top_level.txt,sha256=aZzmI_yecTaDrdSp29pTJuowaSQ9dlIZheQpshGg4YQ,7
|
23
|
+
moteus-0.3.69.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|