130 lines
4.2 KiB
Python
130 lines
4.2 KiB
Python
|
import serial
|
||
|
import matplotlib.pyplot as plt
|
||
|
import matplotlib.animation as animation
|
||
|
from collections import deque
|
||
|
|
||
|
# Adjust this to match your actual serial port and baud rate
|
||
|
SERIAL_PORT = '/dev/ttyACM0' # or COM3 on Windows
|
||
|
BAUD_RATE = 115200
|
||
|
|
||
|
# Set up serial connection
|
||
|
ser = serial.Serial(SERIAL_PORT, BAUD_RATE)
|
||
|
|
||
|
# How many data points to keep in the scrolling buffer
|
||
|
buffer_len = 200
|
||
|
|
||
|
# Create buffers for each sensor pair.
|
||
|
# We'll store them in a dict to keep things organized.
|
||
|
sensor_buffers = {
|
||
|
'wrist_roll': {
|
||
|
'val1': deque([0]*buffer_len, maxlen=buffer_len),
|
||
|
'val2': deque([0]*buffer_len, maxlen=buffer_len)
|
||
|
},
|
||
|
'elbow_pitch': {
|
||
|
'val1': deque([0]*buffer_len, maxlen=buffer_len),
|
||
|
'val2': deque([0]*buffer_len, maxlen=buffer_len)
|
||
|
},
|
||
|
'shoulder_pitch': {
|
||
|
'val1': deque([0]*buffer_len, maxlen=buffer_len),
|
||
|
'val2': deque([0]*buffer_len, maxlen=buffer_len)
|
||
|
},
|
||
|
'shoulder_yaw': {
|
||
|
'val1': deque([0]*buffer_len, maxlen=buffer_len),
|
||
|
'val2': deque([0]*buffer_len, maxlen=buffer_len)
|
||
|
},
|
||
|
'shoulder_roll': {
|
||
|
'val1': deque([0]*buffer_len, maxlen=buffer_len),
|
||
|
'val2': deque([0]*buffer_len, maxlen=buffer_len)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Create a figure with 5 subplots (one for each sensor pair).
|
||
|
fig, axes = plt.subplots(5, 1, figsize=(8, 12), sharex=True)
|
||
|
fig.tight_layout(pad=3.0)
|
||
|
|
||
|
# We'll store line references in a dict so we can update them in our update() function.
|
||
|
lines = {
|
||
|
'wrist_roll': [],
|
||
|
'elbow_pitch': [],
|
||
|
'shoulder_pitch': [],
|
||
|
'shoulder_yaw': [],
|
||
|
'shoulder_roll': []
|
||
|
}
|
||
|
|
||
|
# Set up each subplot
|
||
|
subplot_info = [
|
||
|
('wrist_roll', 'Wrist Roll (2,3)', axes[0]),
|
||
|
('elbow_pitch', 'Elbow Pitch (0,1)', axes[1]),
|
||
|
('shoulder_pitch', 'Shoulder Pitch (10,11)', axes[2]),
|
||
|
('shoulder_yaw', 'Shoulder Yaw (12,13)', axes[3]),
|
||
|
('shoulder_roll', 'Shoulder Roll (14,15)', axes[4])
|
||
|
]
|
||
|
|
||
|
for (sensor_name, label, ax) in subplot_info:
|
||
|
ax.set_title(label)
|
||
|
ax.set_xlim(0, buffer_len)
|
||
|
ax.set_ylim(0, 4096)
|
||
|
line1, = ax.plot([], [], label=f"{sensor_name} - val1")
|
||
|
line2, = ax.plot([], [], label=f"{sensor_name} - val2")
|
||
|
ax.legend()
|
||
|
lines[sensor_name] = [line1, line2]
|
||
|
|
||
|
def update(frame):
|
||
|
# Read all available lines from the serial buffer
|
||
|
while ser.in_waiting:
|
||
|
raw_line = ser.readline().decode('utf-8').strip()
|
||
|
parts = raw_line.split()
|
||
|
|
||
|
# We expect at least 16 values if all sensors are present.
|
||
|
# (Because you mentioned indices 0..1, 2..3, 10..11, 12..13, 14..15)
|
||
|
if len(parts) < 16:
|
||
|
continue
|
||
|
|
||
|
try:
|
||
|
values = list(map(int, parts))
|
||
|
except ValueError:
|
||
|
# If there's a parsing error, skip this line
|
||
|
continue
|
||
|
|
||
|
# Extract the relevant values and append to the correct buffer
|
||
|
sensor_buffers['elbow_pitch']['val1'].append(values[0])
|
||
|
sensor_buffers['elbow_pitch']['val2'].append(values[1])
|
||
|
|
||
|
sensor_buffers['wrist_roll']['val1'].append(values[2])
|
||
|
sensor_buffers['wrist_roll']['val2'].append(values[3])
|
||
|
|
||
|
sensor_buffers['shoulder_pitch']['val1'].append(values[14])
|
||
|
sensor_buffers['shoulder_pitch']['val2'].append(values[15])
|
||
|
|
||
|
sensor_buffers['shoulder_yaw']['val1'].append(values[12])
|
||
|
sensor_buffers['shoulder_yaw']['val2'].append(values[13])
|
||
|
|
||
|
sensor_buffers['shoulder_roll']['val1'].append(values[10])
|
||
|
sensor_buffers['shoulder_roll']['val2'].append(values[11])
|
||
|
|
||
|
# Update each line's data in each subplot
|
||
|
all_lines = []
|
||
|
for (sensor_name, _, ax) in subplot_info:
|
||
|
# x-values are just the index range of the buffer
|
||
|
x_data = range(len(sensor_buffers[sensor_name]['val1']))
|
||
|
|
||
|
# First line
|
||
|
lines[sensor_name][0].set_data(
|
||
|
x_data,
|
||
|
sensor_buffers[sensor_name]['val1']
|
||
|
)
|
||
|
# Second line
|
||
|
lines[sensor_name][1].set_data(
|
||
|
x_data,
|
||
|
sensor_buffers[sensor_name]['val2']
|
||
|
)
|
||
|
|
||
|
all_lines.extend(lines[sensor_name])
|
||
|
|
||
|
return all_lines
|
||
|
|
||
|
# Create the animation
|
||
|
ani = animation.FuncAnimation(fig, update, interval=50, blit=False)
|
||
|
|
||
|
plt.show()
|