import tkinter as tk
from tkinter import PhotoImage
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.animation as animation
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import serial
import time
from serial.serialutil import SerialTimeoutException
import mplcursors
c = 0
memory = [0.0, 0.0, 0.0, 0.0, 0.0]
def read_data():
global memory
ser=serial.Serial('COM13', 9600)
while True:
try:
if ser.in_waiting > 2:
global data_str
packet = ser.readline()
data_str = packet.decode('utf-8').split("<")[1].split(">")[0]
print(data_str)
data_elements = data_str.split(",")
row = [float(data_elements[15]), float(data_elements[16]), float(data_elements[17]), float(data_elements[5]), float(data_elements[3]), int(data_elements[18])]
print(row)
memory=row
yield row
else:
yield memory
except serial.SerialException as e:
print("Serial port error:", e)
yield memory
except Exception as e:
print("An error occurred:", e)
yield memory
def update_plot():
scale=0.1
data_packet = next(data_generator)
ax.cla()
global c
if c == 0:
roll_deg = np.degrees(0)
pitch_deg = np.degrees(0)
yaw_deg = np.degrees(0)
c = 1
else:
roll_deg = np.degrees(data_packet[0]*scale)
pitch_deg = np.degrees(data_packet[2]*scale)
yaw_deg = np.degrees(data_packet[1]*scale)
draw_3d_cylinder(ax, roll_deg, pitch_deg, yaw_deg)
time.append(time[-1] + 1)
index5_data.append(data_packet[3])
index3_data.append(data_packet[4])
ax1.clear()
ax1.plot(time, index5_data, label='Temperature', color='#FF5733')
ax1.legend()
ax1.set_xlabel('Time (sec)', color='white')
ax1.set_ylabel('Temperature (℃)', color='white')
ax1.tick_params(axis='x', colors='white')
ax1.tick_params(axis='y', colors='white')
ax2.clear()
ax2.plot(time, index3_data, label='Altitude/Trajectory', color='#FF5733')
ax2.legend()
ax2.set_xlabel('Time (sec)', color='white')
ax2.set_ylabel('Altitude / Trajectory (m)', color='white')
ax2.tick_params(axis='y', colors='white')
ax2.tick_params(axis='x', colors='white')
canvas.draw()
root.after(800, update_plot)
def draw_3d_cylinder(ax, roll, pitch, yaw):
radius = 0.1
height = 0.2
half_height = height / 2
num_vertices = 20
theta = np.linspace(0, 2 * np.pi, num_vertices)
circle_x = radius * np.cos(theta)
circle_y = radius * np.sin(theta)
vertices_top = np.array([circle_x, circle_y, np.full(num_vertices, half_height)]).T
vertices_bottom = np.array([circle_x, circle_y, np.full(num_vertices, -half_height)]).T
rotation_matrix = np.dot(np.dot(
np.array([[np.cos(yaw), -np.sin(yaw), 0],
[np.sin(yaw), np.cos(yaw), 0],
[0, 0, 1]]),
np.array([[np.cos(pitch), 0, np.sin(pitch)],
[0, 1, 0],
[-np.sin(pitch), 0, np.cos(pitch)]])),
np.array([[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]]))
rotated_vertices_top = np.dot(vertices_top, rotation_matrix.T)
rotated_vertices_bottom = np.dot(vertices_bottom, rotation_matrix.T)
ax.clear()
ax.add_collection3d(Poly3DCollection([rotated_vertices_top], color='orange', alpha=0.6, edgecolor='black'))
ax.add_collection3d(Poly3DCollection([rotated_vertices_bottom], color='#595959', alpha=0.6, edgecolor='black'))
for i in range(num_vertices - 1):
side_vertices = [[rotated_vertices_top[i], rotated_vertices_top[i + 1],
rotated_vertices_bottom[i + 1], rotated_vertices_bottom[i]]]
ax.add_collection3d(Poly3DCollection(side_vertices, color='orange', alpha=0.6, edgecolor='black'))
side_vertices_last = [[rotated_vertices_top[-1], rotated_vertices_top[0],
rotated_vertices_bottom[0], rotated_vertices_bottom[-1]]]
ax.add_collection3d(Poly3DCollection(side_vertices_last, color='orange', alpha=0.6, edgecolor='black'))\
ax.set_xlim([-radius, radius])
ax.set_ylim([-radius, radius])
ax.set_zlim([-half_height, half_height])
ax.xaxis.set_pane_color((0.0, 0.0, 0.0, 0.0))
ax.yaxis.set_pane_color((0.0, 0.0, 0.0, 0.0))
ax.zaxis.set_pane_color((0.0, 0.0, 0.0, 0.0))
ax.grid(True)
ax.tick_params(axis='x', colors='white') # Set x-axis ticks color to white
ax.tick_params(axis='y', colors='white') # Set y-axis ticks color to white
ax.tick_params(axis='z', colors='white')
# ax.set_axis_off()
# ax.set_facecolor('#A9A9A9')
plt.draw()
root = tk.Tk()
root.title("3D Block Animation")
root.configure(bg='#303030')
root.state('zoomed')
# Load the logo image
logo_image = PhotoImage(file="kalpana.png")
# Create a frame for the logo and label
logo_frame = tk.Frame(root, bg='#303030')
logo_frame.pack(side=tk.TOP, padx=10, pady=10)
# Add the logo to the frame
logo_label = tk.Label(logo_frame, image=logo_image, bg='#303030')
logo_label.pack(side=tk.LEFT)
team_label = tk.Label(logo_frame, text="Team Kalpana - ASI049", font=("Helvetica", 14, "bold"), fg="white", bg='#303030')
team_label.pack(side=tk.RIGHT, padx=(10, 0))
# Create main figure and axes for 3D rendering
fig = plt.Figure(facecolor='#303030',dpi=100)
ax = fig.add_subplot(121, projection='3d')
ax.set_facecolor('#303030')
ax.set_axis_off()
# Create subplot for real-time plots
ax1 = fig.add_subplot(224)
ax2 = fig.add_subplot(222)
time = [0]
index5_data = [0]
index3_data = [0]
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
data_generator = read_data()
update_plot() # Start updating the plot
root.mainloop()