# Solar Tracking Art¶

Art based on variants of the single-axis tracking equations.

This example plays around with the cross-axis tilt parameter of the “slope-aware backtracking” method described in 1).

## References¶

1

Kevin Anderson and Mark Mikofski, “Slope-Aware Backtracking for Single-Axis Trackers”, Technical Report NREL/TP-5K00-76626, July 2020. https://www.nrel.gov/docs/fy20osti/76626.pdf

import pvlib
import pandas as pd
from numpy import sin, cos, arctan2, arccos, radians, degrees, sign, array
import matplotlib.pyplot as plt
import imageio
import io

times = pd.date_range('2019-06-01', '2019-06-02', freq='5s', tz='Etc/GMT+5')
location = pvlib.location.Location(40, -80)
solpos = location.get_solarposition(times)
gcr = 0.5

beta_a = 0

s = array([
cos(beta_s) * sin(gamma_s),
cos(beta_s) * cos(gamma_s),
sin(beta_s)
])

frames = []
for i, beta_c in enumerate(radians(range(-90, 90, 2))):
fig = plt.figure()
sp = array([
s[0] * cos(gamma_a) - s[1] * sin(gamma_a),
s[0] * sin(gamma_a) * cos(beta_a) + s[1] * cos(beta_a) * cos(gamma_a) - s[2]*sin(beta_a),
s[0] * sin(gamma_a) * sin(beta_a) + s[1] * sin(beta_a) * cos(gamma_a) + s[2]*cos(beta_a)
])
theta_t = arctan2(sp[0], sp[2])
theta_t = pd.Series(theta_t, index=times)

numerator = abs(cos(theta_t - beta_c))
denominator = gcr * cos(beta_c)
arg = numerator / denominator
arg[abs(arg) > 1] = 1
theta_c = -sign(theta_t) * arccos(arg)
theta_c[theta_c.isnull() & (beta_s > 0)] = 0
degrees(theta_t).plot()
degrees(theta_t + theta_c).plot()

plt.title(fr"$\beta_c$={degrees(beta_c):0.01f}$\degree$")
plt.ylabel(r"Tracker Angle [$\degree$]")
buffer = io.BytesIO()
plt.savefig(buffer)
if beta_c == 0:
# repeat frames at beta_c=0 for visual effect
for i in range(10):
frames.append(buffer)
thumbnail = fig
else:
frames.append(buffer)
plt.close(fig)  # only close if not using for thumbnail

thumbnail.show()

with imageio.get_writer('../../images/solar-tracking-art.gif', mode='I') as writer:
for buffer in frames:
buffer.seek(0)