Skip to content

Ambiguous descriptions of axis_azimuth and axis_tilt in pvlib.tracking.singleaxis() docs #1976

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
williamhobbs opened this issue Feb 20, 2024 · 11 comments

Comments

@williamhobbs
Copy link
Contributor

williamhobbs commented Feb 20, 2024

Is your feature request related to a problem? Please describe.
Some details around axis_azimuth and axis_tilt in the docs (https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.tracking.singleaxis.html) seem ambiguous to me.

Examples:

  1. For a north-south aligned tracker axis, sloping 5 degrees down to the south, what are the inputs for axis_azimuth and axis_tilt? I assume axis_azimuth = 180, axis_tilt = 5.
  2. For the same north-south aligned tracker axis, but sloping 5 degrees down to the north, what are the inputs? I assume axis_azimuth = 0, axis_tilt = 5, since axis_tilt must be >= 0.

Additionally, the description in the docs includes:

For example, if tracker axis_azimuth is 180 (oriented south) and axis_tilt is zero...

But the default for axis_azimuth is 0, which could lead to confusion around inputs and output sign convention.

Describe the solution you'd like
More clear docs.

Additional context
Changing definitions slightly and allowing for negative axis_tilt would make more sense to me, but maybe that causes other problems. [edit: now I don't think this is a good idea - see the full discussion below] [2nd edit: looks like code allows for this even though docs do not. Also, my opinion is easily swayed...]

For example # 2 above (sloping down to the North), allowing for axis_azimuth = 180, axis_tilt = -5 makes more since to me. You could unambigously define axis_azimuth as "the South-most direction of the axis of rotation" and axis_tilt as "the tilt of the axis of rotation, with positive values indicating downward slope towards the South-most direction, and negative values indicating downward slope towards the North-most direction...".

I'm not sure how to handle the odd case of a tracker axis aligned perfectly East-West.

And for systems in the Southern Hemisphere, I don't think anything would need to change.

@mikofski
Copy link
Member

Another argument for allowing negative axis tilt is to keep the common convention that rotation increases during the day, from negative in the morning when facing east to positive in the afternoon & trackers facing west. I think this only works if the axis points south?

@williamhobbs
Copy link
Contributor Author

@mikofski, I agree. Good point.

Keeping a consistent rotation convention makes more sense to me than (the way I interpret) the existing docs for pvlib.tracking.singleaxis(): tracker_theta sign reverses depending on whether you pick 0 or 180 for axis_azimuth.

@williamhobbs
Copy link
Contributor Author

I just ran some tests in NREL SAM using both the detailed PV model and the PVWatts model - in both cases, it does not allow tilt for 1-axis trackers to be less than zero.

The documentation there is also not clear, but it appears that azimuth = 0 and tilt = 5 models a system sloping down to the north, while azimuth = 180 and tilt = 5 models a system sloping down to the south.

So, I can now see a benefit to keeping the conventions in pvlib.tracking.singleaxis() as they are and simply updating the docs a bit. But @mikofski's point about rotation angle convention is still a good one...

@janinefreeman
Copy link

janinefreeman commented Feb 20, 2024

I left a comment on the SAM issue as well, but allowing negative input tilts would require some additional mathematical gymnastics inside the functions to make angle calculations and shading calculations work out (I'm assuming this is true for pvlib as well) - at the very least, transposition to the expected case before doing the math (i.e. if a user enters azimuth = 180, tilt = -5, the code would need to translate that to azimuth = 0, tilt = 5, then correctly re-translate the outputs). I have wondered about this issue of "how to explain which end of the tracker is the rotation around" before, since right now it follows mathematical rotational axis definitions, rather than cardinal direction conventions, that certainly aren't intuitive for most. Open to ideas here on the best way to communicate what tracker rotation angles mean...

Thanks @williamhobbs for linking the issues so we can brainstorm collectively! :)

@williamhobbs
Copy link
Contributor Author

Keeping conventions the same between pvlib and SAM seems like it would be very beneficial to users.

The rotation "convention" of negative in the morning, positive in the afternoon, would stay reversed in the case of sloping down to the North, but 1) this can be clarified in docs, and 2) is likely a pretty rare case. I think anyone that is modeling an atypical system like this and needs to carefully interpret tracker_theta is already pretty far into the "weeds" and can probable make sense of it all with decent docs.

@mikofski
Copy link
Member

@williamhobbs please just try it with negative axis_tilt and see if it works already as expected. I looked through the code here: https://github.com/pvlib/pvlib-python/blob/main/pvlib/tracking.py and I don’t see anything other than the docstring that limits it between zero and 90°. @janinefreeman I believe pvlib should just work even if axis tilt is negative without any changes at all because singleaxis() used arctan2 instead of cosine so should work in any quadrant.

@AdamRJensen
Copy link
Member

I would vote in favor of allowing negative tilts, and thus allowing the standard convention of negative morning and positive evening tilts.

I could easily imagine simulations of larger systems (where the field is broken down into several sub-systems of uniform tilt) where one part of the field is sloping north and another is sloping south. In such a case it would be inconvenient having different axis azimuth conventions for different parts of the field.

@williamhobbs
Copy link
Contributor Author

williamhobbs commented Feb 20, 2024

@mikofski you are correct, it works with negative axis_tilt.

image

(edit: code below)

import pvlib
import matplotlib.pyplot as plt
import pandas as pd

lat, lon = 33.52, -86.81
tz = 'US/Central'

times = pd.date_range('2023-12-21 5:00',
                      '2023-12-21 18:00',
                      freq='5min',
                      tz=tz)

solpos = pvlib.solarposition.get_solarposition(times, lat, lon)

angles_1 = pvlib.tracking.singleaxis(
    apparent_zenith=solpos['apparent_zenith'],
    apparent_azimuth=solpos['azimuth'],
    axis_tilt=0,
    axis_azimuth=180,
    max_angle=50,
    backtrack=True,
    gcr=0.45
)['tracker_theta'].fillna(0)

angles_2 = pvlib.tracking.singleaxis(
    apparent_zenith=solpos['apparent_zenith'],
    apparent_azimuth=solpos['azimuth'],
    axis_tilt=10,
    axis_azimuth=180,
    max_angle=50,
    backtrack=True,
    gcr=0.45
)['tracker_theta'].fillna(0)

angles_3 = pvlib.tracking.singleaxis(
    apparent_zenith=solpos['apparent_zenith'],
    apparent_azimuth=solpos['azimuth'],
    axis_tilt=-10,
    axis_azimuth=0,
    max_angle=50,
    backtrack=True,
    gcr=0.45
)['tracker_theta'].fillna(0)

angles_1.plot()
angles_2.plot()
angles_3.plot()
plt.legend(['tilt=0, az=180', 'tilt=10, az=180', 'tilt=-10, az=0'])
plt.ylabel('Tracker rotation angle, degrees')
plt.xlabel('Local time')
plt.show()

@williamhobbs
Copy link
Contributor Author

Since negative values of axis_tilt are allowed in the code, it seems like users can use either convention and the docs simply need to be updated accordingly. And part of that is noting that if users select axis_azimuth between 270 and 90 (North-facing), the rotation angle convention is reversed.

@cwhanse
Copy link
Member

cwhanse commented Feb 20, 2024

I'm OK with negative axis tilt, as long as the definition of axis_tilt and axis_azimuth are not dependent on hemisphere, and together unambiguously define the coordinate system that defines rotation. I'd be opposed to start with a desired rotation convention (e.g. negative is east) because I'm fairly sure that will make the coordinate system depend on hemisphere.

@matsuobasho
Copy link
Contributor

Taking the above discussion into account, if we specify an axis_azimuth of 0 and an axis_tilt of -5, what does that mean in terms of the positioning of the trackers?

From the way the docstring is currently worded
The tilt of the axis of rotation (i.e, the y-axis defined by axis_azimuth) with respect to horizontal.
seems like it would be a confusing situation where we specify that the azimuth is 0 (point towards north), but also specify that there is a -5 degree tilt, meaning that the slope is actually towards the south?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants