pybricks 3.5.0b2__tar.gz → 3.6.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 (37) hide show
  1. {pybricks-3.5.0b2 → pybricks-3.6.0}/PKG-INFO +4 -3
  2. {pybricks-3.5.0b2 → pybricks-3.6.0}/pyproject.toml +1 -1
  3. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/_common.py +180 -67
  4. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/hubs.py +20 -20
  5. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/parameters.py +4 -0
  6. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/pupdevices.py +6 -2
  7. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/robotics.py +50 -4
  8. {pybricks-3.5.0b2 → pybricks-3.6.0}/AUTHORS.md +0 -0
  9. {pybricks-3.5.0b2 → pybricks-3.6.0}/LICENSE +0 -0
  10. {pybricks-3.5.0b2 → pybricks-3.6.0}/README.rst +0 -0
  11. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/micropython/__init__.py +0 -0
  12. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/micropython/py.typed +0 -0
  13. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/__init__.py +0 -0
  14. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/ev3dev/_speaker.py +0 -0
  15. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/ev3devices.py +0 -0
  16. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/iodevices.py +0 -0
  17. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/media/__init__.py +0 -0
  18. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/media/ev3dev.py +0 -0
  19. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/media/py.typed +0 -0
  20. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/messaging.py +0 -0
  21. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/nxtdevices.py +0 -0
  22. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/py.typed +0 -0
  23. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/pybricks/tools.py +0 -0
  24. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uerrno/__init__.py +0 -0
  25. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uerrno/py.typed +0 -0
  26. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uio/__init__.py +0 -0
  27. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uio/py.typed +0 -0
  28. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/ujson/__init__.py +0 -0
  29. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/umath/__init__.py +0 -0
  30. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/umath/py.typed +0 -0
  31. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/urandom/__init__.py +0 -0
  32. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/urandom/py.typed +0 -0
  33. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uselect/__init__.py +0 -0
  34. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/uselect/py.typed +0 -0
  35. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/ustruct/__init__.py +0 -0
  36. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/usys/__init__.py +0 -0
  37. {pybricks-3.5.0b2 → pybricks-3.6.0}/src/usys/py.typed +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: pybricks
3
- Version: 3.5.0b2
3
+ Version: 3.6.0
4
4
  Summary: Documentation and user-API stubs for Pybricks MicroPython
5
- Home-page: https://pybricks.com
6
5
  License: MIT
7
6
  Author: The Pybricks Authors
8
7
  Author-email: team@pybricks.com
@@ -16,8 +15,10 @@ Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
19
  Classifier: Programming Language :: Python :: Implementation :: MicroPython
20
20
  Project-URL: Documentation, https://docs.pybricks.com
21
+ Project-URL: Homepage, https://pybricks.com
21
22
  Project-URL: Repository, https://github.com/pybricks/pybricks-api
22
23
  Description-Content-Type: text/x-rst
23
24
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pybricks"
3
- version = "3.5.0b2"
3
+ version = "3.6.0"
4
4
  description = "Documentation and user-API stubs for Pybricks MicroPython"
5
5
  authors = ["The Pybricks Authors <team@pybricks.com>"]
6
6
  maintainers = ["Laurens Valk <laurens@pybricks.com>", "David Lechner <david@pybricks.com>" ]
@@ -69,32 +69,6 @@ class System:
69
69
 
70
70
  Stops your program and shuts the hub down."""
71
71
 
72
- def reset_reason(self) -> int:
73
- """reset_reason() -> int
74
-
75
- Finds out how and why the hub (re)booted. This can be useful to
76
- diagnose some problems.
77
-
78
- Returns:
79
- * ``0`` if the hub was previously powered off
80
- normally.
81
- * ``1`` if the hub rebooted automatically, like
82
- after a firmware update.
83
- * ``2`` if the hub previously
84
- crashed due to a watchdog timeout, which indicates a firmware
85
- issue.
86
- """
87
-
88
- def name(self) -> str:
89
- """name() -> str
90
-
91
- Gets the hub name. This is the name you see when connecting
92
- via Bluetooth.
93
-
94
- Returns:
95
- The hub name.
96
- """
97
-
98
72
  @overload
99
73
  def storage(self, offset: int, *, read: int) -> bytes: ...
100
74
 
@@ -131,6 +105,40 @@ class System:
131
105
  If you try to read or write data outside of the allowed range.
132
106
  """
133
107
 
108
+ def reset_storage(self) -> None:
109
+ """reset_storage()
110
+
111
+ Resets all user settings to default values and erases user programs.
112
+ """
113
+
114
+ def info(self) -> dict:
115
+ """info() -> dict
116
+
117
+ Gets information about the hub as a dictionary with the following keys:
118
+
119
+ - ``"name"``: The hub name. This is the name you see when connecting
120
+ via Bluetooth.
121
+ - ``"reset_reason"``: Why the hub (re)booted. It is ``0`` if the hub
122
+ was previously powered off normally. It is ``1`` if the hub rebooted
123
+ automatically, like after a firmware update. It is ``2`` if the hub
124
+ previously crashed due to a watchdog timeout, which indicates a
125
+ firmware issue.
126
+ - ``"host_connected_ble"``: Whether the hub is connected to a computer,
127
+ tablet, or phone via Bluetooth.
128
+ - ``"program_start_type"``: It is ``1`` if the program started
129
+ automatically when the hub was powered on. It is ``2`` if the program
130
+ was started with the hub buttons. It is ``3`` if the program was
131
+ started from your connected computer.
132
+
133
+ Returns:
134
+ A dictionary with system info.
135
+
136
+ .. versionchanged:: 3.6
137
+ The name and reset reason where previously available as separate
138
+ methods. Now they are included in the info dictionary. The methods
139
+ are still available for compatibility.
140
+ """
141
+
134
142
 
135
143
  class DCMotor:
136
144
  """Generic class to control simple motors without rotation sensors, such
@@ -471,6 +479,11 @@ class Motor(DCMotor):
471
479
 
472
480
  Sets the accumulated rotation angle of the motor to a desired value.
473
481
 
482
+ If this motor is also being used by a drive base, its distance and
483
+ angle values will also be affected. You might want to
484
+ use its :meth:`reset <pybricks.robotics.DriveBase.reset>`
485
+ method instead.
486
+
474
487
  Arguments:
475
488
  angle (Number, deg): Value to which the angle should be reset.
476
489
  """
@@ -1013,34 +1026,67 @@ class SimpleAccelerometer:
1013
1026
  """
1014
1027
 
1015
1028
 
1016
- class Accelerometer(SimpleAccelerometer):
1017
- """Get measurements from an accelerometer."""
1029
+ class IMU:
1030
+
1031
+ def up(self, calibrated: bool = True) -> Side:
1032
+ """up(calibrated=True) -> Side
1033
+
1034
+ Checks which side of the hub currently faces upward.
1035
+
1036
+ Arguments:
1037
+ calibrated (bool): Choose ``True`` to use calibrated gyroscope and
1038
+ accelerometer data to determine which way is up. Choose
1039
+ ``False`` to use raw acceleration values.
1040
+
1041
+ Returns:
1042
+ ``Side.TOP``, ``Side.BOTTOM``, ``Side.LEFT``, ``Side.RIGHT``,
1043
+ ``Side.FRONT`` or ``Side.BACK``.
1044
+ """
1045
+
1046
+ def tilt(self, calibrated: bool = True) -> Tuple[int, int]:
1047
+ """tilt(calibrated=True) -> Tuple[int, int]
1048
+
1049
+ Gets the pitch and roll angles. This is relative to the
1050
+ :ref:`user-specified neutral orientation <robotframe>`.
1051
+
1052
+ The order of rotation is pitch-then-roll. This is equivalent to a
1053
+ positive rotation along the robot y-axis and then a positive rotation
1054
+ along the x-axis.
1055
+
1056
+ Arguments:
1057
+ calibrated (bool): Choose ``True`` to use calibrated gyroscope and
1058
+ accelerometer data to determine the tilt. Choose ``False``
1059
+ to use raw acceleration values.
1060
+
1061
+ Returns:
1062
+ Tuple of pitch and roll angles in degrees.
1063
+ """
1018
1064
 
1019
1065
  @overload
1020
- def acceleration(self, axis: Axis) -> float: ...
1066
+ def acceleration(self, axis: Axis = None, calibrated: bool = True) -> float: ...
1021
1067
 
1022
1068
  @overload
1023
- def acceleration(self) -> Matrix: ...
1069
+ def acceleration(self, calibrated: bool = True) -> Matrix: ...
1024
1070
 
1025
1071
  def acceleration(self, *args):
1026
1072
  """
1027
- acceleration(axis) -> float: mm/s²
1028
- acceleration() -> vector: mm/s²
1029
-
1073
+ acceleration(axis, calibrated=True) -> float: mm/s²
1074
+ acceleration(calibrated=True) -> vector: mm/s²
1030
1075
 
1031
1076
  Gets the acceleration of the device along a given axis in the
1032
1077
  :ref:`robot reference frame <robotframe>`.
1033
1078
 
1034
1079
  Arguments:
1035
1080
  axis (Axis): Axis along which the acceleration should be
1036
- measured.
1081
+ measured, or ``None`` to get a vector along all axes.
1082
+ calibrated (bool): Choose ``True`` to use calibrated acceleration
1083
+ values. Choose ``False`` to use raw acceleration values.
1084
+
1037
1085
  Returns:
1038
1086
  Acceleration along the specified axis. If you specify no axis,
1039
1087
  this returns a vector of accelerations along all axes.
1040
1088
  """
1041
1089
 
1042
-
1043
- class IMU(Accelerometer):
1044
1090
  def ready(self) -> bool:
1045
1091
  """ready() -> bool
1046
1092
 
@@ -1068,38 +1114,91 @@ class IMU(Accelerometer):
1068
1114
  @overload
1069
1115
  def settings(
1070
1116
  self,
1117
+ *,
1071
1118
  angular_velocity_threshold: float = None,
1072
1119
  acceleration_threshold: float = None,
1120
+ heading_correction: float = None,
1121
+ angular_velocity_bias: Tuple[float, float, float] = None,
1122
+ angular_velocity_scale: Tuple[float, float, float] = None,
1123
+ acceleration_correction: Tuple[float, float, float, float, float, float] = None,
1073
1124
  ) -> None: ...
1074
1125
 
1075
1126
  @overload
1076
- def settings(self) -> Tuple[float, float]: ...
1127
+ def settings(
1128
+ self,
1129
+ ) -> Tuple[
1130
+ float,
1131
+ float,
1132
+ float,
1133
+ Tuple[float, float, float],
1134
+ Tuple[float, float, float],
1135
+ Tuple[float, float, float, float, float, float],
1136
+ ]: ...
1077
1137
 
1078
1138
  def settings(self, *args):
1079
1139
  """
1080
- settings(angular_velocity_threshold, acceleration_threshold)
1081
- settings() -> Tuple[float, float]
1140
+ settings(*, angular_velocity_threshold, acceleration_threshold, heading_correction, angular_velocity_bias, angular_velocity_scale, acceleration_correction)
1141
+ settings() -> Tuple
1082
1142
 
1083
1143
  Configures the IMU settings. If no arguments are given,
1084
- this returns the current values.
1144
+ this returns the current values. Use keyword arguments for each value
1145
+ to ensure correct behavior because settings may be added or changed in
1146
+ future releases.
1147
+
1148
+ These IMU settings are saved on the hub. They will keep their values
1149
+ until you change them again. The values will be reset to default values
1150
+ if you update the hub to a different firmware version or call the
1151
+ ``hub.system.reset_storage`` method.
1085
1152
 
1086
1153
  The ``angular_velocity_threshold`` and ``acceleration_threshold``
1087
1154
  define when the hub is considered stationary. If all
1088
1155
  measurements stay below these thresholds for one second, the IMU
1089
- will recalibrate itself.
1090
-
1091
- In a noisy room with high ambient vibrations (such as a
1092
- competition hall), it is recommended to increase the thresholds
1156
+ will recalibrate itself. In a noisy room with high ambient vibrations (such as a
1157
+ competition hall), you can increase the thresholds
1093
1158
  slightly to give your robot the chance to calibrate.
1094
1159
  To verify that your settings are working as expected, test that
1095
1160
  the ``stationary()`` method gives ``False`` if your robot is moving,
1096
- and ``True`` if it is sitting still for at least a second.
1161
+ and ``True`` if it is sitting still.
1162
+
1163
+ The gyroscope measures how fast the hub rotates to estimate the total
1164
+ angle. Due to variations in the production process, each
1165
+ hub consistently reports a different value for a full rotation. For
1166
+ example, your hub might consistently report `357` degrees for every
1167
+ `360` degree turn. You can measure this value
1168
+ with ``hub.imu.rotation(-Axis.Z, calibrated=False)`` and enter it as
1169
+ the ``heading_correction`` setting. Then, the ``hub.imu.heading()``
1170
+ method will take it into account going forward, correctly scaling it
1171
+ to 360 degrees for a full rotation.
1097
1172
 
1098
1173
  Arguments:
1099
1174
  angular_velocity_threshold (Number, deg/s): The threshold for
1100
- angular velocity. The default value is 1.5 deg/s.
1101
- acceleration_threshold (Number, mm/s²): The threshold for angular
1102
- velocity. The default value is 250 mm/s².
1175
+ variations in the angular velocity below which the hub is
1176
+ considered stationary enough to calibrate.
1177
+ After a reset the value is 2 deg/s.
1178
+ acceleration_threshold (Number, mm/s²): The threshold for
1179
+ variations in acceleration below which the hub is considered
1180
+ stationary enough to calibrate. After a reset the value
1181
+ is 2500 mm/s².
1182
+ heading_correction (Number, deg): Number of degrees
1183
+ reported by for one full rotation of your robot.
1184
+ After a reset the value is 360 degrees. This is applied on top
1185
+ of any scaling that is done by the ``angular_velocity_scale``
1186
+ setting.
1187
+ angular_velocity_bias (tuple, deg/s): Initial bias for angular
1188
+ velocity measurements along x, y, and z immediately after boot.
1189
+ After a reset the value is (0, 0, 0) deg/s.
1190
+ angular_velocity_scale (tuple, deg): Scale adjustment for x, y, and
1191
+ z rotation to account for manufacturing differences. After a
1192
+ reset the value is (360, 360, 360) deg/s. The correct values
1193
+ can be obtained using `hub.imu.rotation(Axis.X, calibrated=False)`
1194
+ and repeating it for each axis.
1195
+ acceleration_correction (tuple, mm/s²): Scale adjustment for x, y,
1196
+ and z gravity magnitude in both directions to account for
1197
+ manufacturing differences. After a reset the
1198
+ value is (9806.65, -9806.65, 9806.65, -9806.65, 9806.65, -9806.65) mm/s².
1199
+ The correct values can be
1200
+ obtained using `hub.imu.acceleration(Axis.X, calibrated=False)`
1201
+ and repeating it for all axes in both directions.
1103
1202
  """
1104
1203
 
1105
1204
  def heading(self) -> float:
@@ -1117,11 +1216,11 @@ class IMU(Accelerometer):
1117
1216
  the robot is on a flat surface.*
1118
1217
 
1119
1218
  This means that the value is
1120
- no longer correct if you lift it from the table. To solve
1121
- this, you can call ``reset_heading`` to reset the heading to
1122
- a known value *after* you put it back down. For example, you
1123
- could align your robot with the side of the competition table
1124
- and reset the heading 90 degrees as the new starting point.
1219
+ no longer correct if you lift it from the table or turn on
1220
+ a ramp. Try ``hub.imu.heading('3D')`` for a heading value
1221
+ that compensates for this. This will become the default in a
1222
+ future release. If you try it, please let us know on our
1223
+ forums!
1125
1224
 
1126
1225
  Returns:
1127
1226
  Heading angle relative to starting orientation.
@@ -1133,35 +1232,50 @@ class IMU(Accelerometer):
1133
1232
 
1134
1233
  Resets the accumulated heading angle of the robot.
1135
1234
 
1235
+ This cannot be called while a drive base is using the gyro to drive or
1236
+ hold position.
1237
+ Use :meth:`DriveBase.reset() <pybricks.robotics.DriveBase.reset>`
1238
+ instead, which will stop the robot and then set the new heading value.
1239
+
1240
+ .. versionchanged:: 3.6 Resetting the angle while driving is not allowed. Stop first.
1241
+
1136
1242
  Arguments:
1137
1243
  angle (Number, deg): Value to which the heading should be reset.
1244
+
1245
+ Raises:
1246
+ OSError:
1247
+ There is a drive base that is currently using the gyro.
1138
1248
  """
1139
1249
 
1140
1250
  @overload
1141
- def angular_velocity(self, axis: Axis) -> float: ...
1251
+ def angular_velocity(self, axis: Axis = None, calibrated: bool = True) -> float: ...
1142
1252
 
1143
1253
  @overload
1144
- def angular_velocity(self) -> Matrix: ...
1254
+ def angular_velocity(self, calibrated: bool = True) -> Matrix: ...
1145
1255
 
1146
1256
  def angular_velocity(self, *args):
1147
1257
  """
1148
- angular_velocity(axis) -> float: deg/s
1149
- angular_velocity() -> vector: deg/s
1258
+ angular_velocity(axis, calibrated=True) -> float: deg/s
1259
+ angular_velocity(calibrated=True) -> vector: deg/s
1150
1260
 
1151
1261
  Gets the angular velocity of the device along a given axis in
1152
1262
  the :ref:`robot reference frame <robotframe>`.
1153
1263
 
1154
1264
  Arguments:
1155
1265
  axis (Axis): Axis along which the angular velocity should be
1156
- measured.
1266
+ measured, or ``None`` to get a vector along all axes.
1267
+ calibrated (bool): Choose ``True`` to compensate for the estimated
1268
+ bias and configured scale of the gyroscope. Choose ``False``
1269
+ to get raw angular velocity values.
1270
+
1157
1271
  Returns:
1158
1272
  Angular velocity along the specified axis. If you specify no axis,
1159
1273
  this returns a vector of accelerations along all axes.
1160
1274
  """
1161
1275
 
1162
- def rotation(self, axis: Axis) -> float:
1276
+ def rotation(self, axis: Axis, calibrated: bool = True) -> float:
1163
1277
  """
1164
- rotation(axis) -> float: deg
1278
+ rotation(axis, calibrated=True) -> float: deg
1165
1279
 
1166
1280
  Gets the rotation of the device along a given axis in
1167
1281
  the :ref:`robot reference frame <robotframe>`.
@@ -1170,10 +1284,11 @@ class IMU(Accelerometer):
1170
1284
  axis. For general three-dimensional motion, use the
1171
1285
  ``orientation()`` method instead.
1172
1286
 
1173
- The value starts counting from ``0`` when you initialize this class.
1174
-
1175
1287
  Arguments:
1176
1288
  axis (Axis): Axis along which the rotation should be measured.
1289
+ calibrated (bool): Choose ``True`` to compensate for configured
1290
+ scale of the gyroscope. Choose ``False`` to get unscaled values.
1291
+
1177
1292
  Returns:
1178
1293
  The rotation angle.
1179
1294
  """
@@ -1188,10 +1303,8 @@ class IMU(Accelerometer):
1188
1303
  It returns a rotation matrix whose columns represent the ``X``, ``Y``,
1189
1304
  and ``Z`` axis of the robot.
1190
1305
 
1191
- .. note:: This method is not yet implemented.
1192
-
1193
1306
  Returns:
1194
- The rotation matrix.
1307
+ The 3x3 rotation matrix.
1195
1308
  """
1196
1309
 
1197
1310
 
@@ -1335,14 +1448,14 @@ class BLE:
1335
1448
  .. versionadded:: 3.3
1336
1449
  """
1337
1450
 
1338
- def broadcast(self, data: Union[bool, int, float, str, bytes]) -> None:
1451
+ def broadcast(self, data: Union[bool, int, float, str, bytes]) -> MaybeAwaitable:
1339
1452
  """broadcast(data)
1340
1453
 
1341
1454
  Starts broadcasting the given data on
1342
1455
  the ``broadcast_channel`` you selected when initializing the hub.
1343
1456
 
1344
1457
  Data may be of type ``int``, ``float``, ``str``, ``bytes``,
1345
- ``True``, or ``False``, or a list thereof.
1458
+ ``True``, or ``False``. It can also be a list or tuple of these.
1346
1459
 
1347
1460
  Choose ``None`` to stop broadcasting. This helps improve performance
1348
1461
  when you don't need the broadcast feature, especially when observing
@@ -44,9 +44,9 @@ class MoveHub:
44
44
  ble = _common.BLE()
45
45
 
46
46
  def __init__(
47
- self, broadcast_channel: int = 0, observe_channels: Sequence[int] = []
47
+ self, broadcast_channel: int = None, observe_channels: Sequence[int] = []
48
48
  ):
49
- """MoveHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
49
+ """MoveHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
50
50
 
51
51
  Arguments:
52
52
  top_side (Axis): The axis that passes through the *top side* of
@@ -54,8 +54,8 @@ class MoveHub:
54
54
  front_side (Axis): The axis that passes through the *front side* of
55
55
  the hub.
56
56
  broadcast_channel:
57
- A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
58
- will use. Default is channel 0.
57
+ Channel number (0 to 255) used to broadcast data.
58
+ Choose ``None`` when not using broadcasting.
59
59
  observe_channels:
60
60
  A list of channels to listen to when ``hub.ble.observe()`` is
61
61
  called. Listening to more channels requires more memory.
@@ -78,14 +78,14 @@ class CityHub:
78
78
  ble = _common.BLE()
79
79
 
80
80
  def __init__(
81
- self, broadcast_channel: int = 0, observe_channels: Sequence[int] = []
81
+ self, broadcast_channel: int = None, observe_channels: Sequence[int] = []
82
82
  ):
83
- """CityHub(broadcast_channel=0, observe_channels=[])
83
+ """CityHub(broadcast_channel=None, observe_channels=[])
84
84
 
85
85
  Arguments:
86
86
  broadcast_channel:
87
- A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
88
- will use. Default is channel 0.
87
+ Channel number (0 to 255) used to broadcast data.
88
+ Choose ``None`` when not using broadcasting.
89
89
  observe_channels:
90
90
  A list of channels to listen to when ``hub.ble.observe()`` is
91
91
  called. Listening to more channels requires more memory.
@@ -112,10 +112,10 @@ class TechnicHub:
112
112
  self,
113
113
  top_side: Axis = Axis.Z,
114
114
  front_side: Axis = Axis.X,
115
- broadcast_channel: int = 0,
115
+ broadcast_channel: int = None,
116
116
  observe_channels: Sequence[int] = [],
117
117
  ):
118
- """TechnicHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
118
+ """TechnicHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
119
119
 
120
120
  Initializes the hub. Optionally, specify how the hub is
121
121
  :ref:`placed in your design <robotframe>` by saying in which
@@ -128,8 +128,8 @@ class TechnicHub:
128
128
  front_side (Axis): The axis that passes through the *front side* of
129
129
  the hub.
130
130
  broadcast_channel:
131
- A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
132
- will use. Default is channel 0.
131
+ Channel number (0 to 255) used to broadcast data.
132
+ Choose ``None`` when not using broadcasting.
133
133
  observe_channels:
134
134
  A list of channels to listen to when ``hub.ble.observe()`` is
135
135
  called. Listening to more channels requires more memory.
@@ -157,10 +157,10 @@ class EssentialHub:
157
157
  self,
158
158
  top_side: Axis = Axis.Z,
159
159
  front_side: Axis = Axis.X,
160
- broadcast_channel: int = 0,
160
+ broadcast_channel: int = None,
161
161
  observe_channels: Sequence[int] = [],
162
162
  ):
163
- """EssentialHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
163
+ """EssentialHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
164
164
 
165
165
  Initializes the hub. Optionally, specify how the hub is
166
166
  :ref:`placed in your design <robotframe>` by saying in which
@@ -173,8 +173,8 @@ class EssentialHub:
173
173
  front_side (Axis): The axis that passes through the *front side* of
174
174
  the hub.
175
175
  broadcast_channel:
176
- A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
177
- will use. Default is channel 0.
176
+ Channel number (0 to 255) used to broadcast data.
177
+ Choose ``None`` when not using broadcasting.
178
178
  observe_channels:
179
179
  A list of channels to listen to when ``hub.ble.observe()`` is
180
180
  called. Listening to more channels requires more memory.
@@ -212,10 +212,10 @@ class PrimeHub:
212
212
  self,
213
213
  top_side: Axis = Axis.Z,
214
214
  front_side: Axis = Axis.X,
215
- broadcast_channel: int = 0,
215
+ broadcast_channel: int = None,
216
216
  observe_channels: Sequence[int] = [],
217
217
  ):
218
- """PrimeHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=0, observe_channels=[])
218
+ """PrimeHub(top_side=Axis.Z, front_side=Axis.X, broadcast_channel=None, observe_channels=[])
219
219
 
220
220
  Initializes the hub. Optionally, specify how the hub is
221
221
  :ref:`placed in your design <robotframe>` by saying in which
@@ -228,8 +228,8 @@ class PrimeHub:
228
228
  front_side (Axis): The axis that passes through the *front side* of
229
229
  the hub.
230
230
  broadcast_channel:
231
- A value from 0 to 255 indicating which channel ``hub.ble.broadcast()``
232
- will use. Default is channel 0.
231
+ Channel number (0 to 255) used to broadcast data.
232
+ Choose ``None`` when not using broadcasting.
233
233
  observe_channels:
234
234
  A list of channels to listen to when ``hub.ble.observe()`` is
235
235
  called. Listening to more channels requires more memory.
@@ -112,6 +112,10 @@ class Color:
112
112
  The brightness value.
113
113
  """
114
114
 
115
+ def __iter__(self):
116
+ """Allows unpacking of the Color instance into h, s, and v."""
117
+ return iter((self.h, self.s, self.v))
118
+
115
119
  def __repr__(self):
116
120
  return "Color(h={}, s={}, v={})".format(self.h, self.s, self.v)
117
121
 
@@ -86,11 +86,15 @@ class Motor(_common.Motor):
86
86
 
87
87
  Sets the accumulated rotation angle of the motor to a desired value.
88
88
 
89
- If you don't specify an angle, the absolute angle
90
- will be used if your motor supports it.
89
+ If this motor is also being used by a drive base, its distance and
90
+ angle values will also be affected. You might want to
91
+ use its :meth:`reset <pybricks.robotics.DriveBase.reset>`
92
+ method instead.
91
93
 
92
94
  Arguments:
93
95
  angle (Number, deg): Value to which the angle should be reset.
96
+ Choose ``None`` to reset it to the absolute
97
+ value of the motor.
94
98
  """
95
99
 
96
100
 
@@ -119,10 +119,19 @@ class DriveBase:
119
119
  Tuple of distance, drive speed, angle, and turn rate of the robot.
120
120
  """
121
121
 
122
- def reset(self) -> None:
123
- """reset()
122
+ def reset(self, distance: Number = 0, angle: Number = 0) -> None:
123
+ """reset(distance=0, angle=0)
124
124
 
125
- Resets the estimated driven distance and angle to 0."""
125
+ Resets the estimated driven distance and heading angle.
126
+
127
+ This also calls :meth:`.stop` to stop ongoing movements.
128
+ If your robot is controlled with :meth:`.use_gyro` set to ``True``,
129
+ calling this method will `also` set the gyro to the given angle.
130
+
131
+ Arguments:
132
+ distance (Number, mm): Speed of the robot.
133
+ angle (Number, deg): Heading angle of the robot.
134
+ """
126
135
 
127
136
  @overload
128
137
  def settings(
@@ -191,6 +200,40 @@ class DriveBase:
191
200
  with the rest of the program.
192
201
  """
193
202
 
203
+ def arc(
204
+ self,
205
+ radius: Number,
206
+ angle: Number = None,
207
+ distance: Number = None,
208
+ then: Stop = Stop.HOLD,
209
+ wait: bool = True,
210
+ ) -> MaybeAwaitable:
211
+ """arc(radius, angle=None, distance=None, then=Stop.HOLD, wait=True)
212
+
213
+ Drives an arc (a partial circle) with a given radius. You can specify
214
+ how far to drive using either an angle or a distance.
215
+
216
+ With a positive radius, the robot drives along a circle to its right.
217
+ With a negative radius, the robot drives along a circle to its left.
218
+
219
+ You can specify how far to travel along that circle as an angle
220
+ (degrees) or distance (mm). A positive value means driving forward
221
+ along the circle. Negative means driving in reverse.
222
+
223
+ Arguments:
224
+ radius (Number, mm): Radius of the circle.
225
+ angle (Number, deg): Angle to drive along the circle.
226
+ distance (Number, mm): Distance to drive along the circle,
227
+ measured at the center of the robot.
228
+ then (Stop): What to do after coming to a standstill.
229
+ wait (bool): Wait for the maneuver to complete before continuing
230
+ with the rest of the program.
231
+ Raises:
232
+ ValueError:
233
+ You must specify ``angle`` or ``distance``, but not both. The
234
+ radius cannot be zero. Use :meth:`.turn` for in-place turns.
235
+ """
236
+
194
237
  def curve(
195
238
  self, radius: Number, angle: Number, then: Stop = Stop.HOLD, wait: bool = True
196
239
  ) -> MaybeAwaitable:
@@ -224,7 +267,7 @@ class DriveBase:
224
267
  with the maximum actuation signal.
225
268
 
226
269
  Returns:
227
- ``True`` if the drivebase is stalled, ``False`` if not.
270
+ ``True`` if the drive base is stalled, ``False`` if not.
228
271
  """
229
272
 
230
273
  def use_gyro(self, use_gyro: bool) -> None:
@@ -234,6 +277,9 @@ class DriveBase:
234
277
  straight. Choose ``False`` to rely only on the motor's built-in
235
278
  rotation sensors.
236
279
 
280
+ This method will automatically call :meth:`.stop` to stop ongoing
281
+ movements.
282
+
237
283
  Arguments:
238
284
  use_gyro (bool): ``True`` to enable, ``False`` to disable.
239
285
  """
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes