import pandas as pd import numpy as np # --- Tablita que pasaste --- data = [ ("10:30",115.09,52.37), ("10:45",118.65,55.47), ("11:00",122.79,58.46), ("11:15",127.65,61.3), ("11:30",133.43,63.95), ("11:45",140.31,66.33), ("12:00",148.5,68.35), ("12:15",158.07,69.92), ("12:30",168.86,70.91), ("12:45",180.37,71.23), ("13:00",191.86,70.86), ("13:15",202.57,69.82), ("13:30",212.03,68.21), ("13:45",220.12,66.16), ("14:00",226.91,63.76), ("14:15",232.61,61.09), ("14:30",237.41,58.24), ("14:45",241.5,55.24), ("15:00",245.02,52.13), ] df = pd.DataFrame(data, columns=["Hora","Az","Alt"]) # --- Parámetros del tracker --- TILT = 23.2 # inclinación en grados AZ_REAL = 182.0 # orientación real del módulo (ej. 2° al SE) AZ_OFFSET = 26720.0 AZ_SCALE = 605.3 ZENITH_MAX_STEPS = 51500.0 ZENITH_SCALE = 820.0 # --- Funciones auxiliares --- def deg2rad(d): return d*np.pi/180 def rad2deg(r): return r*180/np.pi def sun_to_panel_angles(az, alt, tilt, az_real): # Vector solar global (ENU) sx = np.cos(deg2rad(alt)) * np.sin(deg2rad(az)) sy = np.cos(deg2rad(alt)) * np.cos(deg2rad(az)) sz = np.sin(deg2rad(alt)) # Rotación Z(-AZ_REAL) pr = deg2rad(az_real) x1 = np.cos(pr)*sx + np.sin(pr)*sy y1 = -np.sin(pr)*sx + np.cos(pr)*sy z1 = sz # Rotación X(-TILT) tr = deg2rad(tilt) x2 = x1 y2 = np.cos(tr)*y1 + np.sin(tr)*z1 z2 = -np.sin(tr)*y1 + np.cos(tr)*z1 phi_local = (rad2deg(np.arctan2(x2, y2)) + 360) % 360 alt_local = rad2deg(np.arctan2(z2, np.sqrt(x2**2 + y2**2))) return phi_local, alt_local # --- Calcular pasos --- X_fit, Y_fit = [], [] for _, row in df.iterrows(): phi, altp = sun_to_panel_angles(row["Az"], row["Alt"], TILT, AZ_REAL) zenp = 90 - altp y_steps = -(AZ_OFFSET + phi*AZ_SCALE) x_steps = -(ZENITH_MAX_STEPS - zenp*ZENITH_SCALE) X_fit.append(x_steps) Y_fit.append(y_steps) df["X_fit"] = np.round(X_fit).astype(int) df["Y_fit"] = np.round(Y_fit).astype(int) print(df)