martedì 25 novembre 2025

Disegnatore robot a pantografo

 Questo post deriva dalla curiosita' suscitata dal giocattolo Lisciani Step

 

 

 

 


 

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# ---------------------------------------------------------
# PARAMETRI DEL PANTOGRAFO
# ---------------------------------------------------------

L = 1.0          # lunghezza dei bracci
cx, cy = 0.5, 0.5    # centro del cerchio
R = 0.3          # raggio del cerchio (deve essere <= 2L)
omega = 1.0      # velocità angolare

# ---------------------------------------------------------
# TRAIETTORIA DEL PENNINO
# ---------------------------------------------------------

t = np.linspace(0, 6*np.pi, 600)

Px = cx + R * np.cos(omega * t)
Py = cy + R * np.sin(omega * t)

# ---------------------------------------------------------
# Cinematica inversa (soluzione simmetrica)
# ---------------------------------------------------------
def inv_kin(px, py):
    p = np.array([px, py]) / L
    rho = np.linalg.norm(p)

    if rho > 2:
        raise ValueError("Punto fuori dal workspace del pantografo: ", (px,py))

    phi = np.arctan2(p[1], p[0])
    alpha = np.arccos(rho / 2)

    theta1 = phi + alpha
    theta2 = phi - alpha

    return theta1, theta2

# ---------------------------------------------------------
# Calcolo posizioni dei giunti A, B e del punto P
# ---------------------------------------------------------

A, B, P = [], [], []

for px, py in zip(Px, Py):
    th1, th2 = inv_kin(px, py)

    a = np.array([L*np.cos(th1), L*np.sin(th1)])
    b = np.array([L*np.cos(th2), L*np.sin(th2)])
    p = a + b

    A.append(a)
    B.append(b)
    P.append(p)

A = np.array(A)
B = np.array(B)
P = np.array(P)

# ---------------------------------------------------------
# ANIMAZIONE
# ---------------------------------------------------------

fig, ax = plt.subplots(figsize=(6,6))
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
ax.set_aspect('equal')
ax.set_title("Pantografo – cerchio centrato in (0.5, 0.5) r=0.3")

line_OA, = ax.plot([], [], lw=2)
line_OB, = ax.plot([], [], lw=2)
line_AP, = ax.plot([], [], lw=1, ls='--')
line_BP, = ax.plot([], [], lw=1, ls='--')
pen,      = ax.plot([], [], 'o')
traj,     = ax.plot(P[:,0], P[:,1], alpha=0.2)

def init():
    line_OA.set_data([], [])
    line_OB.set_data([], [])
    line_AP.set_data([], [])
    line_BP.set_data([], [])
    pen.set_data([], [])
    return line_OA, line_OB, line_AP, line_BP, pen

def update(i):
    O = np.array([0,0])
    a = A[i]
    b = B[i]
    p = P[i]

    line_OA.set_data([O[0], a[0]], [O[1], a[1]])
    line_OB.set_data([O[0], b[0]], [O[1], b[1]])
    line_AP.set_data([a[0], p[0]], [a[1], p[1]])
    line_BP.set_data([b[0], p[0]], [b[1], p[1]])

    # FIX richiesto da Matplotlib: sequenze, non scalari
    pen.set_data([p[0]], [p[1]])

    return line_OA, line_OB, line_AP, line_BP, pen

ani = FuncAnimation(fig, update, frames=len(t), init_func=init, blit=True)
plt.show()


 

 

 

Nessun commento:

Posta un commento

Algoritmo Reed Solomon

 Sto progettando una trasmissione radio di immagini ed uno dei vincoli e' che non e' garantita la perfetta qualita' della trasmi...