Skip to content

singleaxis tracking: backtracking error #656

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

Closed
cwhanse opened this issue Feb 4, 2019 · 7 comments · Fixed by #697
Closed

singleaxis tracking: backtracking error #656

cwhanse opened this issue Feb 4, 2019 · 7 comments · Fixed by #697
Labels
Milestone

Comments

@cwhanse
Copy link
Member

cwhanse commented Feb 4, 2019

Describe the bug
Low sun angles with a tilted tracking axis cause an error in the backtracking calculation. Code attempts arcos() of a value outside [-1, 1]

To Reproduce

from pvlib.tracking import singleaxis
result = singleaxis(apparent_zenith=80, apparent_azimuth=338, axis_tilt=30,
                    axis_azimuth=180, max_angle=60, backtrack=True, gcr=0.35)

Expected behavior
tracker angle should set to max_angle

Versions:

  • pvlib.__version__: 0.6.1
  • pandas.__version__: 0.23.3
  • python: 3.6
@kevinsa5
Copy link
Contributor

kevinsa5 commented Feb 7, 2019

I admit I have not read the reference paper, nor do I fully understand the algorithm implementation, but I believe the snippet of interest is this:

if backtrack:
axes_distance = 1/gcr
temp = np.minimum(axes_distance*cosd(wid), 1)
# backtrack angle
# (always positive b/c acosd returns values between 0 and 180)
wc = np.degrees(np.arccos(temp))
# Eq 4 applied when wid in QIV (wid < 0 evalulates True), QI
tracker_theta = np.where(wid < 0, wid + wc, wid - wc)

Changing temp to be constrained on both sides appears to solve the issue:
temp = np.clip(axes_distance*cosd(wid), -1, 1)

@wholmgren wholmgren added this to the 0.6.2 milestone May 2, 2019
@mikofski
Copy link
Member

I was wondering why the issue says the expected outcome was that it should be at the max angle, but the test merged for this shows the output as -50.31051385 - was that a typo, and meant to say, "expected outcome not max angle?"

@wholmgren
Copy link
Member

If I remember correctly, these inputs produced nan before the fix in #697. It's not obvious to me that the expected outcome for these inputs should be max_angle. Maybe the expected outcome in the original post should have stated "tracker angle should be between 0 and +/- max_angle". Or maybe the fix was incomplete. @mikofski do you think the output is wrong?

@mikofski
Copy link
Member

TIL that when the tracker axes are tilted, it's possible for the sun to come from below the trackers, in their reference frame, something I never even considered until I started looking into these low sun angles.

mikofski do you think the output is wrong?

Yes, I believe it may be wrong. I believe the tracker does not need to backtrack, but it is rotating past the max angle of 90[deg] so it's rotation should be 90[deg], and the AOI calculated from that.

I don't think it needs to backtrack because if you turn off backtracking and set the max angle to 180[deg], then it yields:

{'tracker_theta': array([129.68948615]),
 'aoi': array([61.35300178]),
 'surface_azimuth': array([292.53615425]),
 'surface_tilt': array([56.42233095])}

I think the tracker axis tilt and low sun angle have combined to put the sun below the tracker. I don't think it shades the next tracker, but it has exceeded the max angle.

image

If the sun is below the tracker then the shadow of the tracker is cast upwards and would shade the top of the next tracker if the shadow's length LR = L/cos(pi-R) were greater than the pitch between rows, P = L/GCR, so LR > P is the same as cos(pi-R) < GCR, But cos(pi-R) = -cos(R) = -cos(129.7) = 0.64 > 0.35 so no backtracking.

I put together a gist to explain what I think is going on. Basically when R is grater than 90[deg] then the condition for backtracking changes because the sun is now below the trackers, and the angle to calculate LR is now pi - R, otherwise the length is negative.

The patch applied in #697 also sees cos(R)/gcr < 1 but the np.clip sets the backtracking to 180 because np.arccos(-1) = 180.

IMHO the trackers would not backtrack all the way to the east, unless this was a special bifacial tracking solution. For monofacial trackers I think they would stop at the stow position.

@mikofski
Copy link
Member

Moreover, I think this AOI is for the backside that is still facing west.

@cwhanse
Copy link
Member Author

cwhanse commented Nov 21, 2019

that when the tracker axes are tilted, it's possible for the sun to come from below the trackers

It's possible that this happens under very restricted conditons: the sun has to be behind all possible planes to which the modules could be rotated, which would restrict the sun to a relatively narrow "triangle" of azimuth (base) and elevation (height) centered at north azimuth (for a north-south tracker). Do you think we've got a case where this happens?

@mikofski
Copy link
Member

Yes, I think this particular case of the 30deg tilted tracker and the low sun angle leads to the rays coming from below the trackers in their reference frame. If you check the solar angle in the yz place it's 10deg, but the tracker is tilted 30deg. If you rotate the solar vector into the tracker reference frame you get the sun in x'z' plane coming in 39.7deg below the tracker. That's why your get a tracker rotation of 129.7deg (=90+39.7) if you turn off backtracking and set max angle to 180deg.

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

Successfully merging a pull request may close this issue.

4 participants