Lesson 22 - Robot Telemetry & Pose
Learning Objective
- Query instant 2D pose coordinates
(x, y, heading)and traveled distance usingBonicBot. - Inspect onboard hardware status telemetry including battery percentage and IMU orientation quaternions.
- Synchronize telemetry stream readiness using
bot.wait_for_data().
Introduction
State estimation allows a robot to track where it is in the world and monitor hardware health metrics. The bonicbot_bridge SDK maintains background subscriptions to odometry, IMU, and system status topics through SensorManager.
This lesson covers querying live pose coordinates, traveled distance, battery levels, and IMU data.
Code
from bonicbot_bridge import BonicBot
with BonicBot(host="192.168.0.188") as bot:
print("1. Waiting up to 5s for active sensor telemetry stream...")
ready = bot.wait_for_data(timeout=5.0, require_imu=True)
print("Telemetry active:", ready)
# 2. Reading Pose Coordinates
pose_dict = bot.get_position()
print("Full Pose Dict:", pose_dict)
x = bot.get_x()
y = bot.get_y()
heading = bot.get_heading()
print(f"Individual Pose Components -> X: {x:.2f}m | Y: {y:.2f}m | Heading: {heading:.1f}°")
# 3. Traveled Distance & Battery Status
dist = bot.get_distance_traveled()
battery = bot.get_battery()
print(f"Distance Traveled: {dist:.2f}m | Battery Level: {battery}%")
# 4. IMU Orientation Quaternions
imu_data = bot.get_imu_data()
imu_orient = bot.get_imu_orientation()
print("IMU Orientation Quaternion:", imu_orient)Expected Output
Click to see expected output
🤖 Connected to BonicBot at 192.168.0.188:9090
1. Waiting up to 5s for active sensor telemetry stream...
Telemetry active: True
Full Pose Dict: {'x': 0.14, 'y': -0.02, 'theta': 358.7}
Individual Pose Components -> X: 0.14m | Y: -0.02m | Heading: 358.7°
Distance Traveled: 0.00m | Battery Level: 85.0%
IMU Orientation Quaternion: {'x': 0.0, 'y': 0.0, 'z': 0.01, 'w': 0.999}
🔌 Disconnected from BonicBot🔧 Under the Hood
How get_position() parses odometry in sensors.py
get_position() parses odometry in sensors.pySensorManager subscribes to /odometry/filtered. get_position() converts the quaternion orientation (z, w) into 2D yaw degrees via 2 * atan2(z, w) and converts radians to degrees.
Student Challenge
Challenge 1 — Python Only
Write a function quaternion_to_yaw_deg(z, w) that computes heading in degrees from quaternion parameters z and w.
Click to see solution
import math
def quaternion_to_yaw_deg(z, w):
yaw_rad = 2.0 * math.atan2(z, w)
yaw_deg = math.degrees(yaw_rad)
return yaw_deg % 360.0
print("Yaw angle for (z=0.707, w=0.707):", round(quaternion_to_yaw_deg(0.707, 0.707), 1), "deg")Challenge 2 — Robot
Read the robot’s initial position start_pos = bot.get_position(), drive forward 0.5m, and print bot.get_distance_traveled(start_pos).
Click to see solution
from bonicbot_bridge import BonicBot
with BonicBot(host="192.168.0.188") as bot:
bot.wait_for_data(timeout=3.0)
start_pos = bot.get_position()
bot.drive_distance(dist=0.5, speed=0.2)
elapsed = bot.get_distance_traveled(start_pos)
print(f"Calculated distance traveled from start: {elapsed:.3f}m")Quick Reference
Pose Methods
| Method | Return Type | Description |
|---|---|---|
bot.get_position() | dict | Returns {'x': ..., 'y': ..., 'theta': ...} |
bot.get_x() | float | Current X coordinate in meters |
bot.get_y() | float | Current Y coordinate in meters |
bot.get_heading() | float | Current heading in degrees (0-360°) |
bot.get_distance_traveled(start) | float | Distance traveled in meters |
Reflection Questions
Why is it necessary to convert 3D quaternion orientations (x, y, z, w) into 2D yaw angles theta for ground mobile robots?
What is the advantage of calling wait_for_data() before querying initial pose attributes in your scripts?