.. title: Single-axis tracking and backtracking, part 1
.. slug: single-axis-tracking-and-backtracking-part-1
.. date: 2020-02-05 18:52:19-07:00
.. tags: pv, python
.. category:
.. link:
.. description:
.. type: text
.. has_math: True
The tracking algorithm used in most commercial PV tracking systems is fairly
sophisticated. It has to be able to know where the sun is and how to orient
the array to best take advantage of the available sunlight. Let's figure out
how they work!
.. TEASER_END
At the basic level, the goal of tracking is to point the panels towards the sun
as directly as possible. This maximizes module exposure to beam irradiance, which
makes up the majority of incoming sunlight. Tracking can be implemented any
number of ways. One of the more exotic methods involved black balloons filled
with a volatile liquid. The balloons were placed under each side of the modules
so that when the modules faced away from the sun, the exposed balloon heats up
and expands, pushing the modules until the light is blocked. I'll leave the
downsides to this approach as an exercise for the reader.
Another "empirical" approach is to detect solar position electronically and rotate
appropriately with a motor. The internet is full of toy examples of this approach
(`for instance `_)
because photodiodes are cheap and because this approach dynamically detects solar
position, you don't have to go to any trouble aligning the tracker mount or worrying
about what time of year it is or where in the world you are. However, relying
on instrumentation to determine the optimal angle is a little risky -- the angle
calculation would get thrown off by stray reflections, small obstructions
(grasshoppers!), snow accumulation, sensor drift...
The most common approach is to use a mathematical model to calculate solar position
based on array location and time of day and calculate the optimal tracker position
with a little trigonometry.
Solar Position
--------------
One of the most popular methods of determining the position of astronomical
bodies is to use pre-made ephemeris tables (e.g. JPL Horizons [1]_). Another
method (and the default in pvlib-python [2]_) is the NREL Solar Position
Algorithm (SPA) [3]_. The SPA is fairly complex (the `current pvlib implementation
`_
is over 1000 lines of code), but highly accurate, capable of calculating
solar zenith and azimuth angles in the period from the year -2000 to 6000,
with uncertainties of :math:`\pm0.0003^\circ`
So suffice to say it'll be fine for our purposes. Given a latitude, longitude,
and datetime, we can calculate solar position to a much higher precision than
any tracker could take advantage of. Technically the SPA also requires
pressure, temperature, and atmospheric refraction but these have small effect
and pvlib supplies suitable default values.
Tracker Geometry
----------------
Look at this excellent diagram:
.. image:: /images/solar_position_3d.jpg
:align: center
Credit: *Submerged and Floating Photovoltaic Systems: Modelling, Design and Case Studies*.
Marco Rosa-Clot and Giuseppe Marco Tina, 2018.
Unfortunately it's for a south-facing system and we're talking about N-S axis systems
that rotate E-W.
Using the labeling in that diagram, the SPA gives us solar zenith :math:`\theta_z`
and solar azimuth :math:`\gamma_s`. Because our trackers can only rotate in a
single axis, we can collapse the N-S axis without losing any necessary information.
Look at this crappy diagram:
.. image:: /images/solar_position_2d.png
:align: center
This is looking along the N-S tracker axis and :math:`x` is along the E-W axis.
:math:`\phi` is both the solar zenith angle adjusted for the N-S collapse and the
tracker angle that aligns the row as directly as possible towards the sun.
Once solar position is determined, calculating the tracker angle that minimizes
angle of incidence is pretty straightforward:
.. math::
x = \sin \theta_z \sin \gamma_s
.. math::
z = \cos \theta_z
.. math::
\tan \phi = \frac{x}{z}
Very easy!
.. code-block:: python
:number-lines:
import pandas as pd
import numpy as np
import pvlib
times = pd.date_range('2019-03-01', '2019-03-02', freq='5min', tz='US/Eastern')
location = pvlib.location.Location(40, -80, tz='US/Eastern')
solpos = location.get_solarposition(times)
solpos = np.radians(solpos)
x = np.sin(solpos.zenith) * np.sin(solpos.azimuth)
z = np.cos(solpos.zenith)
phi = np.degrees(np.arctan2(x, z))
phi[z < 0] = 0
phi.plot()
.. image:: /images/truetracking_angle.png
:align: center
It has all the properties you'd expect -- facing straight east in the morning,
rotates to flat at midday, and faces straight west in evening. This is the "basic"
tracking pattern and is called true-tracking.
References
----------
.. [1] JPL HORIZONS emphemerides https://ssd.jpl.nasa.gov/?ephemerides
.. [2] pvlib.solarposition https://pvlib-python.readthedocs.io/en/stable/api.html#solar-position
.. [3] I. Reda and A. Andreas, Solar position algorithm for solar radiation
applications. Solar Energy, vol. 76, no. 5, pp. 577-589, 2004.
https://midcdmz.nrel.gov/spa/