CanSat-India-Updated / GUI-screen 2 / main.py
main.py
Raw
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

def read_data():
    ser = serial.Serial('COM8', 9600)
    while True:
        packet = ser.readline()
        try:
            data_str = packet.decode('utf-8').split("<")[1].split(">")[0]
            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])]
            yield row
        except UnicodeDecodeError:
            print("UnicodeDecodeError: Ignoring invalid byte sequence")
            continue

def update_plot():
    data_packet = next(data_generator)
    ax.cla()
    roll_deg = np.degrees(data_packet[0])
    pitch_deg = np.degrees(data_packet[2])
    yaw_deg = np.degrees(data_packet[1])
    draw_3d_cylinder(ax, roll_deg, pitch_deg, yaw_deg)
    
    # Update real-time plots
    time.append(time[-1] + 1)  # Increment time by 1 second
    index5_data.append(data_packet[3])  # Append new data for index 5
    index3_data.append(data_packet[4])  # Append new data for index 3
    
    ax1.clear()
    ax1.plot(time, index5_data, label='Temperature', color='#FF5733')  # Change color here
    ax1.legend()
    ax1.set_xlabel('Time (sec)', color='white')
    ax1.set_ylabel('Temperature (℃)', color='white')  # Change color here
    ax1.tick_params(axis='y', colors='white') 
    ax1.tick_params(axis='x', colors='white') # Change color here
    
    ax2.clear()  
    ax2.plot(time, index3_data, label='Altitude/Trajectory', color='#FF5733')  # Change color here
    ax2.legend()  
    ax2.set_xlabel('Time (sec)', color='white')  
    ax2.set_ylabel('Altitude / Trajectory (m)', color='white')  # Change color here
    ax2.tick_params(axis='y', colors='white')  
    ax2.tick_params(axis='x', colors='white')# Change color here
    
    canvas.draw()
    root.after(1000, 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)

    # Define cylinder vertices without rotation
    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

    # Combine rotation matrices around x, y, and z axes into one
    rotation_matrix = np.dot(np.dot(
        np.array([[np.cos(roll), 0, np.sin(roll)],
                  [0, 1, 0],
                  [-np.sin(roll), 0, np.cos(roll)]]),
        np.array([[np.cos(pitch), -np.sin(pitch), 0],
                  [np.sin(pitch), np.cos(pitch), 0],
                  [0, 0, 1]])),
        np.array([[1, 0, 0],
                  [0, np.cos(yaw), -np.sin(yaw)],
                  [0, np.sin(yaw), np.cos(yaw)]]))

    # Rotate vertices around all three axes simultaneously
    rotated_vertices_top = np.dot(vertices_top, rotation_matrix.T)
    rotated_vertices_bottom = np.dot(vertices_bottom, rotation_matrix.T)

    # Draw the cylinder
    ax.clear()
    ax.add_collection3d(Poly3DCollection([rotated_vertices_top], color='#595959', 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(False)
    ax.set_axis_off()
    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)  # Adjust padding as needed

# 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')
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()