State and sensor data¶
Every decision your program makes comes from a value it read: a stick position, a gyro rate, a battery voltage. This page is about where those values come from, how old they might be, and how to tell when one should not be trusted.
Reading a value from MARLIN never makes your program wait. In the background,
MARLIN keeps a copy of the most recent data it received from the robot and the
controller. When you read a property or call read(), you get that stored copy
straight away.
This means a read always succeeds, but the value can be old. The ok field
below is how you tell the difference.
Sensor readings¶
Every sensor reading includes:
| Field | Meaning |
|---|---|
timestamp |
Robot-brain time in milliseconds when the sample was taken |
age |
Approximate milliseconds since the sample was taken |
ok |
True when the reading is usable: the data arrived intact and is no more than 250 ms old |
Check ok before you use a reading to decide how the robot moves. If it is
False, the number is missing or too old to trust, so stop instead of steering
on a stale value:
reading = robot.imu("S1").read()
if reading.ok:
gyro_z = reading.gyro_z
else:
robot.thruster("M1").set_duty(0)
Before a sensor has sent anything, read() still works, but it returns an empty
reading: timestamp == 0, age == math.inf (infinity), and ok == False. This
is normal for the first moments after your program starts.
The extension and robot synchronise time when possible. During local or simulated operation without a synchronised offset, age falls back to time since the sample was received.
Units¶
| Value | Unit or range |
|---|---|
IMU acceleration (accel_x, accel_y, accel_z) |
g |
IMU gyro (gyro_x, gyro_y, gyro_z) |
degrees per second |
IMU magnetometer (mag_x, mag_y, mag_z) |
raw integers |
Radio beacon signal (rssi) |
dBm |
Radio beacon signal-to-noise (snr) |
dB |
| Controller scaled axes | -100 to 100 |
| Controller raw axes | the unprocessed stick number, 0 to 4095 |
| Battery voltage | volts |
rssi and snr describe signal quality, not distance. The library has no
distance measurement. A stronger (less negative) rssi usually means the
beacon is nearer, but RSSI is not a distance reading.
Controller state¶
Controller input is available through robot.controller. Sticks and buttons
are both looked up by name:
left = robot.controller.joystick("ONE").value # -100 to 100
right = robot.controller.joystick("THREE").value # -100 to 100
a_is_down = robot.controller.button("A").is_down # True or False
The controller has two physical sticks, and MARLIN treats each stick's two directions as a separate, single-axis joystick:
| Name | Physical axis |
|---|---|
"ONE" |
Left stick, up and down |
"TWO" |
Left stick, left and right |
"THREE" |
Right stick, up and down |
"FOUR" |
Right stick, left and right |
An unknown joystick name raises ValueError, so a typo stops your program
instead of reading zero forever. Button names are checked the same way. See
below.
Controller state comes from the Controller's own input packets. It can remain
available even when robot.link_ok is false, as long as the extension and
Controller connection are still operating.
Buttons expose only is_down. To detect a new press, keep the last value in a
variable and compare consecutive loop
iterations:
previous = False
while robot.running:
current = robot.controller.button("A").is_down
if current and not previous:
print("A was just pressed")
previous = current
The button names are A, B, X, Y, UP, DOWN, LEFT, RIGHT,
LEFT_TRIGGER, and RIGHT_TRIGGER. Case does not matter. See
Controller input for the diagram they come
from.
Any other name raises ValueError, so a misspelled button stops your program
instead of reporting False forever. If a button never seems to respond, check
its spelling against that list first.
Robot status¶
The robot exposes cached status through read-only properties:
robot.overtemp is true while the robot brain has shut itself down to avoid
overheating. It trips at 50 °C and clears once the board cools to 45 °C. Like
estopped, your program can read it but cannot change it. See
Safety ownership.
Watch out at startup: a value of False or 0.0 can mean "the robot has not
reported yet" rather than "the robot reported a real zero". A battery_voltage
of 0.0 in the first moments does not mean the battery is flat.
So do not make a decision from a status value the instant your program starts. Wait for the link first: