RSI-PI/src/RSIPI/graphing.py

122 lines
4.5 KiB
Python

import time
import logger
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# ✅ Configure Logging for Graphing Module
LOGGING_ENABLED = True
if LOGGING_ENABLED:
logging.basicConfig(
filename="graphing.log",
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%d-%m-%Y %H:%M:%S"
)
class RSIGraphing:
"""Handles real-time and CSV-based graphing for RSI analysis."""
def __init__(self, csv_file=None):
"""Initialize graphing for real-time plotting or CSV replay."""
self.csv_file = csv_file
self.fig, self.ax = plt.subplots(1, 2, figsize=(12, 5)) # ✅ Two subplots: Time-Series & X-Y Trajectory
# ✅ Titles and Labels
self.ax[0].set_title("Real-Time Position Tracking")
self.ax[0].set_xlabel("Time")
self.ax[0].set_ylabel("Position (mm)")
self.ax[1].set_title("2D Trajectory (X-Y)")
self.ax[1].set_xlabel("X Position")
self.ax[1].set_ylabel("Y Position")
# ✅ Data storage for plotting
self.time_data = []
self.x_data, self.y_data, self.z_data = [], [], []
self.actual_x, self.actual_y, self.actual_z = [], [], []
self.trajectory_x, self.trajectory_y = [], []
self.plot_mode = "TCP" # ✅ Toggle between "TCP" and "Joints"
if csv_file:
self.load_csv_log(csv_file)
self.plot_csv_data()
else:
self.ani = animation.FuncAnimation(self.fig, self.update_graph, interval=500, save_count=100)
plt.show()
def update_graph(self, frame):
"""Update the live graph with new position data."""
timestamp = time.strftime("%H:%M:%S")
self.time_data.append(timestamp)
# ✅ Simulated Data for Testing (Replace with real-time data)
self.x_data.append(len(self.time_data) * 10)
self.y_data.append(len(self.time_data) * 5)
self.z_data.append(len(self.time_data) * 2)
self.actual_x.append(len(self.time_data) * 9.8)
self.actual_y.append(len(self.time_data) * 4.9)
self.actual_z.append(len(self.time_data) * 1.8)
# ✅ 2D Trajectory (X-Y)
self.trajectory_x.append(len(self.time_data) * 9.8)
self.trajectory_y.append(len(self.time_data) * 4.9)
# ✅ Clear and replot data
self.ax[0].clear()
self.ax[0].plot(self.time_data, self.x_data, label="Planned X", linestyle="dashed")
self.ax[0].plot(self.time_data, self.y_data, label="Planned Y", linestyle="dashed")
self.ax[0].plot(self.time_data, self.z_data, label="Planned Z", linestyle="dashed")
self.ax[0].plot(self.time_data, self.actual_x, label="Actual X", marker="o")
self.ax[0].plot(self.time_data, self.actual_y, label="Actual Y", marker="o")
self.ax[0].plot(self.time_data, self.actual_z, label="Actual Z", marker="o")
self.ax[0].legend()
self.ax[0].set_title(f"Real-Time {self.plot_mode} Position")
self.ax[0].set_xlabel("Time")
self.ax[0].set_ylabel("Position (mm)")
# ✅ 2D Trajectory (X-Y)
self.ax[1].clear()
self.ax[1].plot(self.trajectory_x, self.trajectory_y, label="Actual Path", marker="o")
self.ax[1].set_title("2D Trajectory (X-Y)")
self.ax[1].set_xlabel("X Position")
self.ax[1].set_ylabel("Y Position")
self.ax[1].legend()
def load_csv_log(self, filename):
"""Load a CSV log and replay motion."""
df = pd.read_csv(filename)
self.time_data = df["Timestamp"].tolist()
self.trajectory_x = df["Receive.RIst.X"].tolist()
self.trajectory_y = df["Receive.RIst.Y"].tolist()
logging.info(f"Loaded CSV log: {filename}")
def plot_csv_data(self):
"""Plot data from a CSV file for post-analysis."""
plt.figure(figsize=(10, 5))
plt.plot(self.trajectory_x, self.trajectory_y, label="Planned Path", linestyle="dashed")
plt.scatter(self.trajectory_x, self.trajectory_y, color='red', label="Actual Path", marker="o")
plt.title("CSV Replay: 2D Trajectory (X-Y)")
plt.xlabel("X Position")
plt.ylabel("Y Position")
plt.legend()
plt.show()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="RSI Graphing Utility")
parser.add_argument("--csv", help="Path to CSV file for replay mode", type=str)
args = parser.parse_args()
if args.csv:
RSIGraphing(csv_file=args.csv)
else:
RSIGraphing() # Run in live mode if no CSV is provided