scirodev 0.3.0__tar.gz → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scirodev
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev
5
5
  Author: Thomas Schank
6
6
  License: MIT
@@ -50,6 +50,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
50
50
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
51
51
  ```
52
52
 
53
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
54
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
55
+ `examples/` here stays minimal.
56
+
53
57
  On the hub these modules are frozen into the PeakHub firmware:
54
58
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
55
59
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
@@ -30,6 +30,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
30
30
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
31
31
  ```
32
32
 
33
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
34
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
35
+ `examples/` here stays minimal.
36
+
33
37
  On the hub these modules are frozen into the PeakHub firmware:
34
38
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
35
39
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scirodev"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -4,6 +4,7 @@ class lives now). Kept so older programs keep type-checking.
4
4
 
5
5
  from .pump import ( # noqa: F401 (re-exports)
6
6
  IMU as IMU,
7
+ Gyro as Gyro,
7
8
  ColorSensor as ColorSensor,
8
9
  FloorPro as FloorPro,
9
10
  IRCalib as IRCalib,
@@ -49,6 +49,15 @@ class PUMPDevice:
49
49
  ``{"url": str, "serial": str, "streams": ((id, url, ext_port, state_len), ...)}``
50
50
  """
51
51
 
52
+ def stats(self) -> Dict[str, Union[int, Tuple[Tuple[int, int, int], ...]]]:
53
+ """stats() -> Dict
54
+
55
+ Link counters since the session started, for load tests and diagnostics:
56
+ ``{"frames": good frames received, "crc_errors", "cobs_errors",
57
+ "short_frames", "overflows", "streams": ((id, frames, gaps), ...)}``
58
+ where ``gaps`` counts frames of that stream the hub never received.
59
+ """
60
+
52
61
  def state(self, stream: int) -> Optional[bytes]:
53
62
  """state(stream) -> bytes | None
54
63
 
@@ -75,5 +84,6 @@ class PUMPDevice:
75
84
  """subscribe(stream, mode, rate=0)
76
85
 
77
86
  Changes only the stream-control word (keeps the device-specific state
78
- bytes). ``rate`` is in units of 10 Hz, 0 = every sample.
87
+ bytes). ``rate`` is in Hz (1 .. 255; higher values are clamped to 255),
88
+ 0 = every sample.
79
89
  """
@@ -28,3 +28,14 @@ class Port(_PybricksEnum):
28
28
  F: Port = ord("F")
29
29
  G: Port = ord("G")
30
30
  H: Port = ord("H")
31
+
32
+
33
+ class ExtPort:
34
+ """Extension port of a PUMP device (1-based, as in its stream table)."""
35
+
36
+ EXT1: int = 1
37
+ EXT2: int = 2
38
+ EXT3: int = 3
39
+ EXT4: int = 4
40
+ EXT5: int = 5
41
+ EXT6: int = 6
@@ -8,10 +8,10 @@ value directly, or an awaitable under multitasking.
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
- from typing import TYPE_CHECKING, Optional, Tuple
11
+ from typing import TYPE_CHECKING, Iterable, Optional, Tuple, Union
12
12
 
13
13
  if TYPE_CHECKING:
14
- from pybricks._common import MaybeAwaitable, MaybeAwaitableFloat
14
+ from pybricks._common import MaybeAwaitable, MaybeAwaitableColor, MaybeAwaitableFloat
15
15
 
16
16
  from ._common import (
17
17
  MaybeAwaitableEuler,
@@ -24,6 +24,8 @@ if TYPE_CHECKING:
24
24
 
25
25
  from .iodevices import PUMPDevice as PUMPDevice # noqa: F401 (re-export)
26
26
  from .iodevices import StreamInfo
27
+ from pybricks.parameters import Color
28
+
27
29
  from .parameters import Port as _Port
28
30
 
29
31
 
@@ -32,7 +34,7 @@ class _Stream:
32
34
  id: int
33
35
 
34
36
  def subscribe(self, mode: int, rate: int = 0) -> MaybeAwaitable:
35
- """subscribe(mode, rate=0) -- see :meth:`PUMPDevice.subscribe`."""
37
+ """subscribe(mode, rate=0) -- rate in Hz, 0 = every sample; see :meth:`PUMPDevice.subscribe`."""
36
38
 
37
39
  def state(self) -> Optional[bytes]:
38
40
  """state() -> bytes | None -- the stream's current state prefix."""
@@ -94,15 +96,49 @@ class Pixels(_Stream):
94
96
 
95
97
 
96
98
  class ColorSensor(_Stream):
97
- """TCS3400 on an extension port: raw R, G, B, C at device resolution.
99
+ """TCS3400 colour sensor on an extension port of a PUMP device.
100
+
101
+ ``ColorSensor(port, ext_port)`` opens it directly; :meth:`FloorPro.color_sensor`
102
+ returns the same class. ``hsv()`` and ``color()`` follow
103
+ ``pybricks.pupdevices.ColorSensor``.
98
104
 
99
105
  Every sample is tagged with the settings it was measured under, so a read
100
106
  after a settings change waits for the first sample taken with the new
101
107
  settings.
102
108
  """
103
109
 
110
+ ext_port: int
111
+
112
+ def __init__(self, port: Union[_Port, PUMPDevice], ext_port: int = 1):
113
+ """ColorSensor(port, ext_port=ExtPort.EXT1)
114
+
115
+ Arguments:
116
+ port (Port): Hub port of the PUMP device carrying the sensor (or the
117
+ opened ``PUMPDevice`` itself).
118
+ ext_port (ExtPort): Extension port the sensor is plugged into.
119
+ Raises ``OSError`` if there is no colour sensor there.
120
+ """
121
+
104
122
  def read(self) -> MaybeAwaitableRGBC:
105
- """read() -> Tuple[int, int, int, int, int] -- (red, green, blue, clear, status)."""
123
+ """read() -> Tuple[int, int, int, int, int] -- raw (red, green, blue, clear, status) at device resolution."""
124
+
125
+ def hsv(self) -> MaybeAwaitableColor:
126
+ """hsv() -> Color
127
+
128
+ Hue (0 .. 359), saturation (0 .. 100) and value (0 .. 100) of the
129
+ surface, as a ``Color``. Standard HSV of the raw reading; value is
130
+ relative to the full scale of the current integration time.
131
+ """
132
+
133
+ def color(self) -> MaybeAwaitableColor:
134
+ """color() -> Color
135
+
136
+ The nearest of the detectable colours (default: red, yellow, green,
137
+ blue, white, none), matched like ``pybricks.pupdevices.ColorSensor``.
138
+ """
139
+
140
+ def detectable_colors(self, colors: Optional[Iterable[Color]] = None) -> Optional[Tuple[Color, ...]]:
141
+ """detectable_colors(colors) -- set the colours color() chooses from; with no argument, get them."""
106
142
 
107
143
  def settings(self) -> Tuple[int, int, int]:
108
144
  """settings() -> Tuple[int, int, int] -- (led_percent, gain_x, atime) in effect."""
@@ -117,13 +153,26 @@ class ColorSensor(_Stream):
117
153
  """set_integration(atime) -- TCS3400 ATIME register 0 .. 255: (256 - atime) * 2.78 ms."""
118
154
 
119
155
 
120
- class IMU(_Stream):
121
- """BNO086 on an extension port: roll, pitch, yaw in degrees.
156
+ class Gyro(_Stream):
157
+ """Gyro (BNO086) on an extension port of a PUMP device: roll, pitch, yaw in degrees.
122
158
 
123
- The heading offset lives on the hub: :meth:`reset_heading` makes the current
124
- yaw read as the given angle.
159
+ ``Gyro(port, ext_port)`` opens it directly; :meth:`FloorPro.gyro` returns the
160
+ same class (``IMU`` is an alias). The heading offset lives on the hub:
161
+ :meth:`reset_heading` makes the current yaw read as the given angle.
125
162
  """
126
163
 
164
+ ext_port: int
165
+
166
+ def __init__(self, port: Union[_Port, PUMPDevice], ext_port: int = 2):
167
+ """Gyro(port, ext_port=ExtPort.EXT2)
168
+
169
+ Arguments:
170
+ port (Port): Hub port of the PUMP device carrying the gyro (or the
171
+ opened ``PUMPDevice`` itself).
172
+ ext_port (ExtPort): Extension port the gyro is plugged into. Raises
173
+ ``OSError`` if there is no gyro there.
174
+ """
175
+
127
176
  def read(self) -> MaybeAwaitableEuler:
128
177
  """read() -> Tuple -- (roll, pitch, yaw, status), degrees; yaw includes the offset."""
129
178
 
@@ -134,6 +183,10 @@ class IMU(_Stream):
134
183
  """reset_heading(angle=0) -- make the current heading read as ``angle``."""
135
184
 
136
185
 
186
+ IMU = Gyro
187
+ """Alias of :class:`Gyro`."""
188
+
189
+
137
190
  class FloorPro:
138
191
  """LP-FloorPro connected to a PeakHub port, speaking PUMP."""
139
192
 
@@ -161,8 +214,11 @@ class FloorPro:
161
214
  The TCS3400 on extension port 1 or 2; raises ``OSError`` if none.
162
215
  """
163
216
 
164
- def imu(self, ext_port: int = 2) -> IMU:
165
- """imu(ext_port=2) -> IMU -- the BNO086 on extension port 1 or 2; raises ``OSError`` if none."""
217
+ def gyro(self, ext_port: int = 2) -> Gyro:
218
+ """gyro(ext_port=2) -> Gyro -- the gyro on extension port 1 or 2; raises ``OSError`` if none."""
219
+
220
+ def imu(self, ext_port: int = 2) -> Gyro:
221
+ """imu(ext_port=2) -> Gyro -- alias of :meth:`gyro`."""
166
222
 
167
223
  def streams(self) -> Tuple[StreamInfo, ...]:
168
224
  """streams() -> Tuple -- the enumerated streams ``(id, url, ext_port, state_len)``."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scirodev
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: PeakHub / sciro extensions to Pybricks: typed API stubs (sciro.*) and hub tooling on top of pybricksdev
5
5
  Author: Thomas Schank
6
6
  License: MIT
@@ -50,6 +50,10 @@ cog_dark, cog_bright, brightness, darkness, mask, calibrating = fp.line.read()
50
50
  hub.display.device(fp, brightness=50) # mirror the sensor's LED strip on the 5x5
51
51
  ```
52
52
 
53
+ Full demo programs for the LP FloorPro (both for LEGO hubs and the PeakHub) live in
54
+ [sciurus-robotics/FloorPro-CodeDemos](https://github.com/sciurus-robotics/FloorPro-CodeDemos);
55
+ `examples/` here stays minimal.
56
+
53
57
  On the hub these modules are frozen into the PeakHub firmware:
54
58
  `sciro.parameters` and `sciro.iodevices` re-export the same runtime objects as
55
59
  their `pybricks.*` counterparts, so `sciro.parameters.Port is
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes