Sensors and readings¶
Robot.configure() creates sensor objects. Each sensor's read() method
returns the latest cached sample. It does not block.
Note
You may configure at most 2 IMU sensors and at most 1 RadioBeacon sensor.
configure() raises a ValueError if you configure more.
Sensor¶
Base class for sensor types. It is public for extension and advanced use.
Normally, pass concrete classes to configure() instead of constructing
sensors directly.
Attributes¶
read¶
Input: none. Output: a reading object holding the latest cached sample.
Returns a base reading. Concrete sensor subclasses return their typed reading:
IMU.read() returns an ImuReading, RadioBeacon.read() returns a
RadioBeaconReading.
Call read() once per loop and keep the result in a variable. Each call returns
a fresh object, so comparing two separate calls compares two snapshots:
reading = robot.imu("S1").read() # one snapshot, used twice below
if reading.ok:
print(reading.gyro_z)
Reading¶
Base dataclass shared by every reading. A dataclass is a plain Python class that holds named fields. You read its fields. You never build one yourself.
| Field | Type | Meaning |
|---|---|---|
timestamp |
int |
Robot-brain sample time in milliseconds |
age |
float |
Sample age in milliseconds |
ok |
bool |
True only when the payload is valid and the age is at most 250 ms |
IMU¶
Nine-axis inertial measurement unit. It reports acceleration, angular rate, and raw magnetometer values. It does not report heading, bearing, or orientation.
Always name the port you declared in configure():
ImuReading¶
ImuReading(
timestamp: int,
age: float,
ok: bool,
accel_x: float,
accel_y: float,
accel_z: float,
gyro_x: float,
gyro_y: float,
gyro_z: float,
mag_x: int,
mag_y: int,
mag_z: int,
)
| Fields | Unit |
|---|---|
accel_x, accel_y, accel_z |
g |
gyro_x, gyro_y, gyro_z |
degrees per second |
mag_x, mag_y, mag_z |
raw integer values |
RadioBeacon¶
LoRa radio-beacon telemetry sensor. It reports signal strength and beacon identity. It does not report distance.
Always name the port you declared in configure():
RadioBeaconReading¶
RadioBeaconReading(
timestamp: int,
age: float,
ok: bool,
rssi: float,
snr: float,
beacon_id: int,
rx_count: int,
)
| Field | Unit or type | Meaning |
|---|---|---|
rssi |
dBm | LoRa signal strength |
snr |
dB | LoRa signal-to-noise ratio |
beacon_id |
int |
Identifies which beacon sent the packet |
rx_count |
int |
Counts packets received from the beacon |
RSSI shows signal strength. It does not show distance. A stronger signal usually means the beacon is nearer, but RSSI is not a distance measurement.
RSSI uses a logarithmic scale. Its unit is dBm. Readings are almost always negative numbers.
A value closer to zero means a stronger signal. For example, -40 dBm is a strong signal. -90 dBm is a weak signal.
The example below uses -80 as a threshold. This threshold is not a
fixed distance. It is only an example. Test the threshold with your own
beacon and your own field. Choose your own threshold from that test.
Missing and stale samples¶
Before a sample arrives, typed readings show these values:
timestampis0.ageismath.inf.okisFalse.- All sensor fields are zero.
The sensor keeps the last sample available after it becomes stale. ok
becomes False when the sample age is more than 250 ms.
Always check ok before you use a reading to command motion.