moteus 0.3.57__py3-none-any.whl → 0.3.58__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/command.py CHANGED
@@ -19,6 +19,7 @@ class Command():
19
19
  reply_required = False
20
20
  data = b''
21
21
  can_prefix = 0x0000 # a 13 bit CAN prefix
22
+ expected_reply_size = 0
22
23
 
23
24
  # If True, then the following parameters are used directly instead
24
25
  # of being calculated from destination and source (i.e. for
moteus/moteus.py CHANGED
@@ -606,7 +606,7 @@ class Controller:
606
606
  self._can_prefix = can_prefix
607
607
 
608
608
  # Pre-compute our query string.
609
- self._query_data = self._make_query_data()
609
+ self._query_data, self._default_query_reply_size = self._make_query_data()
610
610
 
611
611
  def _get_transport(self):
612
612
  if self.transport:
@@ -618,6 +618,8 @@ class Controller:
618
618
  return self.transport
619
619
 
620
620
  def _make_query_data(self):
621
+ expected_reply_size = 0
622
+
621
623
  buf = io.BytesIO()
622
624
  writer = Writer(buf)
623
625
  qr = self.query_resolution
@@ -633,6 +635,8 @@ class Controller:
633
635
  for i in range(c1.size()):
634
636
  c1.maybe_write()
635
637
 
638
+ expected_reply_size += c1.reply_size
639
+
636
640
  c2 = mp.WriteCombiner(writer, 0x10, int(Register.MOTOR_TEMPERATURE), [
637
641
  qr.motor_temperature,
638
642
  qr.trajectory_complete,
@@ -644,6 +648,8 @@ class Controller:
644
648
  for i in range(c2.size()):
645
649
  c2.maybe_write()
646
650
 
651
+ expected_reply_size += c2.reply_size
652
+
647
653
  c3 = mp.WriteCombiner(writer, 0x10, int(Register.AUX1_GPIO_STATUS), [
648
654
  qr.aux1_gpio,
649
655
  qr.aux2_gpio,
@@ -651,6 +657,8 @@ class Controller:
651
657
  for i in range(c3.size()):
652
658
  c3.maybe_write()
653
659
 
660
+ expected_reply_size += c3.reply_size
661
+
654
662
  if len(qr._extra):
655
663
  min_val = int(min(qr._extra.keys()))
656
664
  max_val = int(max(qr._extra.keys()))
@@ -660,8 +668,9 @@ class Controller:
660
668
  for i in range(min_val, max_val +1)])
661
669
  for _ in range(c4.size()):
662
670
  c4.maybe_write()
671
+ expected_reply_size += c4.reply_size
663
672
 
664
- return buf.getvalue()
673
+ return buf.getvalue(), expected_reply_size
665
674
 
666
675
  def _make_command(self, *, query, source=0):
667
676
  result = cmd.Command()
@@ -671,6 +680,7 @@ class Controller:
671
680
  result.reply_required = query
672
681
  result.parse = self._parser
673
682
  result.can_prefix = self._can_prefix
683
+ result.expected_reply_size = self._default_query_reply_size if query else 0
674
684
 
675
685
  return result
676
686
 
@@ -702,6 +712,7 @@ class Controller:
702
712
  c.maybe_write()
703
713
 
704
714
  result.data = buf.getvalue()
715
+ result.expected_reply_size = c.reply_size
705
716
  return result
706
717
 
707
718
  async def custom_query(self, *args, **kwargs):
@@ -1157,6 +1168,7 @@ class Controller:
1157
1168
  result.parse = make_diagnostic_parser(self.id, channel)
1158
1169
 
1159
1170
  result.data = data_buf.getvalue()
1171
+ result.expected_reply_size = 3 + max_length
1160
1172
  return result
1161
1173
 
1162
1174
  async def diagnostic_read(self, *args, **kwargs):
moteus/moteus_tool.py CHANGED
@@ -818,7 +818,8 @@ class Stream:
818
818
  await self.check_for_fault()
819
819
 
820
820
  enc_kp, enc_ki, enc_bw_hz = await self.set_encoder_filter(
821
- torque_bw_hz, control_rate_hz=control_rate_hz)
821
+ torque_bw_hz, inductance,
822
+ control_rate_hz=control_rate_hz)
822
823
  await self.check_for_fault()
823
824
 
824
825
  v_per_hz = await self.calibrate_kv_rating(
@@ -1163,7 +1164,7 @@ class Stream:
1163
1164
  print(f"Calculated inductance: {inductance}H")
1164
1165
  return inductance
1165
1166
 
1166
- async def set_encoder_filter(self, torque_bw_hz, control_rate_hz = None):
1167
+ async def set_encoder_filter(self, torque_bw_hz, inductance, control_rate_hz = None):
1167
1168
  # Check to see if our firmware supports encoder filtering.
1168
1169
  motor_position_style = await self.is_config_supported("motor_position.sources.0.pll_filter_hz")
1169
1170
  servo_style = await self.is_config_supported("servo.encoder_filter.enabled")
@@ -1173,18 +1174,17 @@ class Stream:
1173
1174
  if self.args.encoder_bw_hz:
1174
1175
  desired_encoder_bw_hz = self.args.encoder_bw_hz
1175
1176
  else:
1176
- if self.args.cal_hall:
1177
- # Hall effect configurations require a low encoder BW
1178
- # if the hall effects are also used for position and
1179
- # velocity control. Since that is one of the most
1180
- # common ways of using hall effects, we by default cap
1181
- # the bw at 20Hz and use a lower one if the torque bw
1182
- # would otherwise have been lower.
1183
- desired_encoder_bw_hz = min(20, 2 * torque_bw_hz)
1184
- else:
1185
- # We default to an encoder bandwidth of 50Hz, or 2x the
1186
- # torque bw, whichever is larger.
1187
- desired_encoder_bw_hz = max(50, 2 * torque_bw_hz)
1177
+ # Don't let the encoder bandwidth be less than 10Hz by default.
1178
+ desired_encoder_bw_hz = max(10, 2 * torque_bw_hz)
1179
+
1180
+ # However, we limit the maximum encoder bandwidth for high
1181
+ # inductance motors, because they shouldn't be able to
1182
+ # accelerate that fast anyways.
1183
+ if inductance:
1184
+ # This is just a random constant that seems to work
1185
+ # well in practice.
1186
+ desired_encoder_bw_hz = min(
1187
+ desired_encoder_bw_hz, 2e-2 / inductance)
1188
1188
 
1189
1189
  # And our bandwidth with the filter can be no larger than
1190
1190
  # 1/10th the control rate.
@@ -1203,7 +1203,8 @@ class Stream:
1203
1203
  await self.command(f"conf set servo.encoder_filter.kp {kp}")
1204
1204
  await self.command(f"conf set servo.encoder_filter.ki {ki}")
1205
1205
  elif motor_position_style:
1206
- await self.command(f"conf set motor_position.sources.0.pll_filter_hz {encoder_bw_hz}")
1206
+ commutation_source = await self.read_config_int("motor_position.commutation_source")
1207
+ await self.command(f"conf set motor_position.sources.{commutation_source}.pll_filter_hz {encoder_bw_hz}")
1207
1208
  else:
1208
1209
  assert False
1209
1210
  return kp, ki, encoder_bw_hz
moteus/multiplex.py CHANGED
@@ -244,21 +244,30 @@ class WriteFrame:
244
244
 
245
245
  def __init__(self, buf):
246
246
  self._buf = buf
247
+ self._size = 0
248
+
249
+ def size(self):
250
+ return self._size
247
251
 
248
252
  def write(self, value, resolution):
249
253
  self._buf.write(TYPES[resolution].pack(value))
254
+ self._size += TYPES[resolution].size
250
255
 
251
256
  def write_int8(self, value):
252
257
  self._buf.write(TYPES[INT8].pack(value))
258
+ self._size += 1
253
259
 
254
260
  def write_int16(self, value):
255
261
  self._buf.write(TYPES[INT16].pack(value))
262
+ self._size += 2
256
263
 
257
264
  def write_int32(self, value):
258
265
  self._buf.write(TYPES[INT32].pack(value))
266
+ self._size += 4
259
267
 
260
268
  def write_f32(self, value):
261
269
  self._buf.write(TYPES[F32].pack(value))
270
+ self._size += 4
262
271
 
263
272
  def write_varuint(self, value):
264
273
  while True:
@@ -266,6 +275,7 @@ class WriteFrame:
266
275
  value >>= 7
267
276
  this_byte |= 0x80 if value else 0x00
268
277
  self._buf.write(bytes([this_byte]))
278
+ self._size += 1
269
279
 
270
280
  if value == 0:
271
281
  break
@@ -286,6 +296,7 @@ class WriteCombiner:
286
296
  self.base_command = base_command
287
297
  self.start_register = start_register
288
298
  self.resolutions = resolutions
299
+ self.reply_size = 0
289
300
  self._offset = 0
290
301
  self._current_resolution = -1
291
302
 
@@ -320,6 +331,8 @@ class WriteCombiner:
320
331
 
321
332
  write_command = [0x00, 0x04, 0x08, 0x0c][new_resolution] | self.base_command
322
333
 
334
+ start_size = self.writer.size()
335
+
323
336
  if count <= 3:
324
337
  # Use the shorthand formulation.
325
338
  self.writer.write_int8(write_command + count)
@@ -329,4 +342,10 @@ class WriteCombiner:
329
342
  self.writer.write_int8(count)
330
343
 
331
344
  self.writer.write_varuint(self.start_register + this_offset)
345
+
346
+ end_size = self.writer.size()
347
+
348
+ self.reply_size += end_size - start_size
349
+ self.reply_size += count * resolution_size(new_resolution)
350
+
332
351
  return True
moteus/version.py CHANGED
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- VERSION="0.3.57"
15
+ VERSION="0.3.58"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: moteus
3
- Version: 0.3.57
3
+ Version: 0.3.58
4
4
  Summary: moteus brushless controller library and tools
5
5
  Home-page: https://github.com/mjbots/moteus
6
6
  Author: mjbots Robotic Systems
@@ -2,22 +2,22 @@ moteus/__init__.py,sha256=1Prmih65X7Qz7WY8AUiSwUWXz3Dev8ggQS9xohL75M0,721
2
2
  moteus/aioserial.py,sha256=lOBFPXManRBMsjMc1zuyw-NRt6CNVMvnj_mQqIZLpyI,1061
3
3
  moteus/aiostream.py,sha256=SLDXwdBMHIWVTAmeUGG6ke7sntfNVxd9CqapzfniJOo,3678
4
4
  moteus/calibrate_encoder.py,sha256=kY6mV1WkgCrD9z2YpRoqTTK_BUrRfop4_YJym9AQI-I,12403
5
- moteus/command.py,sha256=YEtDNXX-TlkUSElsGVQoSYbGqcboneNEejZo06v8ZsI,1128
5
+ moteus/command.py,sha256=IXb0ToAg74fm8FYKPiOdjlzxosqdafLhqADffCvw5OY,1156
6
6
  moteus/export.py,sha256=dI8QjdqrcI3pi5fKfP25PwLvsIlVJ695x0ta0PVMKx8,1628
7
7
  moteus/fdcanusb.py,sha256=AMwqdvIRz4X9yA4qz8REuyFBfs3OcLcVqbGX28sEx4s,6729
8
- moteus/moteus.py,sha256=W-ADEI1uAHF0j5A3s1CINTUYpwjEgO-xPRQS15C9Ewg,43410
9
- moteus/moteus_tool.py,sha256=WSJH5kRRF3SSsocGR_TFbRwAeGP0YlexMpes9iS_rt0,66794
10
- moteus/multiplex.py,sha256=0Hs63pFZpl1y7ciTcwEeg8F2JDjlhrkb2FcfUbdox-g,9637
8
+ moteus/moteus.py,sha256=J7nzalhDTUvJq3h1FNjFnYLkrSVnL_IGDU1sw2PNsmU,43869
9
+ moteus/moteus_tool.py,sha256=L-7IBs9YHcbd2nc8SPwCEinHvzp09iVb_JeQCUtNM2U,66800
10
+ moteus/multiplex.py,sha256=EBOhAE-DHkS_AXtqUl2YEs745evvLMPIMeXQSYxF8zk,10102
11
11
  moteus/posix_aioserial.py,sha256=3JFiY5p4dtC2ztg6N5SOffnNk9lNcjie02yjD3UlJWo,2971
12
12
  moteus/pythoncan.py,sha256=lawewmkd9zQuE-Z1LurmpFD2iSWATei65SZb42um_Vg,3309
13
13
  moteus/reader.py,sha256=jGADQTmONSBMQ25I5AqXELLqil2TEha1KjraPdOsf78,11932
14
14
  moteus/regression.py,sha256=wpPlxAZ9nC9kfv0oX1K9W2AZNnBLbY8htAJz60SxIb8,1183
15
15
  moteus/router.py,sha256=k4Tf6hWtHSgzznmdnj4NySe84-y9feYRxGz0yTrJtoc,2043
16
16
  moteus/transport.py,sha256=3asI2A87eQDImLP74LNLtETaShQRiD9RuCjlxNY6AlE,1003
17
- moteus/version.py,sha256=MFTT8rAzrh1zN6v98RZRdgK04yThpVW45c1KwhhP0SU,609
17
+ moteus/version.py,sha256=zpTmrEA7ncnYPk73r5YQJOdYXTB_LBw60As5aQhXRA0,609
18
18
  moteus/win32_aioserial.py,sha256=SZsnoBWE0Uwo4ZZF8ALB1WNPRY9NiaCOBz6VfvVcnxA,1841
19
- moteus-0.3.57.dist-info/METADATA,sha256=HNeottaB3MbXGZcq5Jn_knhHxdKt7I5o-93DKOwOivI,3417
20
- moteus-0.3.57.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
21
- moteus-0.3.57.dist-info/entry_points.txt,sha256=indCsEML1fmtWJU1WiV-d7UmmTaAMhyBLEc1iiKnexQ,57
22
- moteus-0.3.57.dist-info/top_level.txt,sha256=aZzmI_yecTaDrdSp29pTJuowaSQ9dlIZheQpshGg4YQ,7
23
- moteus-0.3.57.dist-info/RECORD,,
19
+ moteus-0.3.58.dist-info/METADATA,sha256=WCPxHMe0doKijEQK9-XAaN5FjXUxTLVdsFn1lRvP4wE,3417
20
+ moteus-0.3.58.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
21
+ moteus-0.3.58.dist-info/entry_points.txt,sha256=indCsEML1fmtWJU1WiV-d7UmmTaAMhyBLEc1iiKnexQ,57
22
+ moteus-0.3.58.dist-info/top_level.txt,sha256=aZzmI_yecTaDrdSp29pTJuowaSQ9dlIZheQpshGg4YQ,7
23
+ moteus-0.3.58.dist-info/RECORD,,