sensors.InertialSensor
- class sensors.InertialSensor(port: Optional[int] = None)
Sensor for measuring relative acceleration, rotation, and angular velocity. Also referred to as the “Inertial Measurement Unit” or IMU for short.
- acceleration() Vector3
Instantaneous acceleration in meters per second per second relative to the sensors current orientation. A slight filter is applied. For an unfiltered version, see
acceleration_stream()
.The following code block assumes an interial sensor is assigned to port 0 and a
TextScreen
is attatched to port 1.from sensors import InertialSensor from controllables import TextScreen from color import Color imu = InertialSensor(0) screen = TextScreen(1) while True: screen.text = f"{imu.acceleration(): 4.0f}" redness = min(1,max(0,imu.acceleration().magnitude() / 10)) screen.color = Color(redness,1 - redness,0)
- acceleration_stream() Stream[Vector3]
Creates an unfiltered stream of acceleration values in meters per second per second relative to the sensors current orientation.
from sensors import InertialSensor from controllables import TextScreen from time import time from vector import Vector3 stream = InertialSensor().acceleration_stream() acceleration_threshold = 5 screen = TextScreen() screen.text = '' time_of_last_color_hit = time() while True: for acceleration in stream: flattened = Vector3.project_onto_plane(acceleration,[0,1,0]) if flattened.magnitude() > acceleration_threshold: time_of_last_color_hit = time() screen.text = "We've changed velocity!" if time() - time_of_last_color_hit > 1: screen.text = '' pass
- rotation_axis() Vector3
Axis of rotation whose magnitude is the magnitude of the rotation in radians.
A value of
<x = tau/2.,y = 0,z = 0>
means a half rotation about the x axis. A rotation of<x = 1/sqrt(2),y = 1/sqrt(2),z = 0> * tau/4.0
does not have anything to do with rotations about either the x or y axis, but is instead a quarter rotation around the diagonal vector pointing up and to the right.The returned axis is the rotation required to rotate from the sensor’s initial orientation to its current one. The axis is given in the space of the sensors current axes.
The following example assumes that an inertial sensor is assigned to port 0 and a
ServoMotor
is assigned to port 1. It assumes that the motor and sensor are sitting on the base of a moving robot and that the motor is placed facing up. The script will try keep the motor’s arm pointed in the direction in which it was initially facing.from sensors import InertialSensor from controllables import ServoMotor from vector import Vector3 imu = InertialSensor(0) servo = ServoMotor(1) while True: servo.spin_to(-imu.rotation_axis().y)
- rotation_stream() Stream[Vector3]
Creates an unfiltered stream of rotation axis values in radians.
from sensors import InertialSensor from scriptruntime import Runtime from controllables import TextScreen from math import tau stream = InertialSensor().rotation_stream() screen = TextScreen() integrated_rotation = 0 while True: for rot in stream: rot_y = rot.y % tau if rot_y > tau / 2: rot_y -= tau integrated_rotation += rot.y * Runtime.sample_duration() screen.text = f'integral of rotation: {integrated_rotation: 0.2f}'
- euler_angles() Vector3
Returns the pitch, yaw and roll of the sensor in the form of a vector3 where x, y, and z components are respectively pitch, yaw and roll in radians.
from sensors import InertialSensor from controllables import TextScreen sensor = InertialSensor() screen = TextScreen() while True: [pitch,yaw,roll] = sensor.euler_angles() screen.text = f'pitch: {pitch: 5.2f}\n' + \ f'yaw: {yaw: 5.2f}\n' + \ f'roll: {roll: 5.2f}\n'
- x_unit() Vector3
The vector, with length 1, pointed in the part’s x axis relative to the part’s original orientation.
from sensors import InertialSensor from controllables import TextScreen sensor = InertialSensor() screen = TextScreen() while True: right = sensor.x_unit() screen.text = f'right: {right: 5.1f}'
- y_unit() Vector3
The vector, with length 1, pointed in the part’s y axis relative to the part’s original orientation.
from sensors import InertialSensor from controllables import TextScreen sensor = InertialSensor() screen = TextScreen() while True: flipped = sensor.y_unit().y < 0 screen.text = f'flipped? {flipped}'
- z_unit() Vector3
The vector, with length 1, pointed in the part’s z axis relative to the part’s original orientation.
from sensors import InertialSensor from controllables import TextScreen sensor = InertialSensor() screen = TextScreen() while True: forward = sensor.z_unit() screen.text = f'forward: {forward: 5.1f}'
- angular_velocity() Vector3
Angular velocity relative to the sensors current orientation in radians per second. A velocity of
<2 * tau,0,0>
means the sensor is rotating around it’s own x axis twice per second. A slight filter is applied, seeangular_velocity_stream()
for an unfiltered version.from sensors import InertialSensor from controllables import TextScreen sensor = InertialSensor() screen = TextScreen() while True: screen.text = f'angular velocity: {sensor.angular_velocity(): 5.1f}'
- angular_velocity_stream() Stream[Vector3]
Creates an stream of angular velocity values in radians per second.
from sensors import InertialSensor from controllables import TextScreen from time import time stream = InertialSensor().angular_velocity_stream() vel_threshold = 5 screen = TextScreen() screen.text = '' time_of_last_turn = time() while True: for vel in stream: if vel.magnitude() > vel_threshold: time_of_last_turn = time() screen.text = "We've been turned too fast!" if time() - time_of_last_turn > 1: screen.text = ''
- class MotionData(rotation_axis: Vector3, angular_velocity: Vector3, acceleration: Vector3)
Holds rotation, angular velocity, and acceleration data from the same sample.
See
motion_data_stream()
for example usage.
- motion_data_stream() Stream[MotionData]
Creates a stream which contains samples from each data stream together such that in a given data object all samples were recorded simultaneously. The values all correspond directly to the other streams avaliable in this class.
The following example gets the motion data from an
InertialSensor
on port0
and outputs the velocity to aTextScreen
on port1
.from sensors import InertialSensor from matrix import Matrix4x4 from scriptruntime import Runtime from vector import Vector3 from controllables import TextScreen imu = InertialSensor(0) output = TextScreen(1) stream = imu.motion_data_stream() dt = Runtime.sample_duration() velocity = Vector3(0,0,0) while True: for sample in stream: acc = sample.acceleration rot = sample.rotation_axis rot_matrix = Matrix4x4.from_rotation(rot) # rotate the acceleration to get a vector relative to a fixed frame dv = rot_matrix * acc # use the sample duration here to do the integration velocity += dv * dt output.text = f"{velocity:+4.1f}"
- name() str
Returns the user editable name of the controllable as found in the properties tab of the game.
The following example assumes that any controllable or sensor is assigned to port
0
and prints out its name.from ports import PortReference print(PortReference(0).name())