-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Singleaxis tracking with non-parallel slope #823
Singleaxis tracking with non-parallel slope #823
Conversation
- add calc_axis_tilt and calc_side_slope functions to tracking.py - add tests for trackers on slopes - add singleaxis tracker w/slope test data Signed-off-by: Mark Mikofski <bwana.marko@yahoo.com>
- match pvlib algorithms - despite disagreement
- remove unused _get_solar_vector, oops! not part of this pr, was decreasing coverage
note: the travis py35-min is failing because the numpy requirement is 1.10.4, when |
I think your backtracking correction is a little different from the one I derived. It's not immediately clear to me, but adding Either way, I'm not sure I understand the max_angle shifting. Is the idea that the tracker motors are installed facing away from the slope so that their zero-point is now off-vertical? Is that something that installers will actually do? |
I am using the existing backtracking algorithm in
I didn't intend it to be "a rotation of one row around another". My intention of adding the side slope to the rotation is transform the reference frame from horizontal (or tilted tracker axis ref. frame) to the system plane. Because the side slope is perpendicular to the tracker axes, then adding it to the tracker rotation just makes it relative to the system plane reference frame. EG: for NS trackers on an eastern slope of 9[deg], an 11[deg] tracker rotation in the horizontal plane would be 20[deg] (or 2[deg] depending on the tracker azimuth) in the reference frame of the eastern slope. I'm not familiar with the
Please do point out any errors! Thanks!
The
It would appear that way, but this is only for convenience. This algorithm doesn't require trackers to be installed in any particular way at all. However, unless pvlib changes the |
Thanks for the explanations! The
I was indeed assuming that axis spacing (and GCR) are measured horizontally. I've been thinking about tracking arrays on side slopes as just arrays on flat terrain where each row has been raised vertically compared to its neighbor -- i.e. horizontal distance between rows is what defines the array geometry and is independent of slope. This just comes from my limited experience in utility scale development where the array was designed and modeled assuming flat terrain, so the system GCR was calculated using horizontal distance and the array built accordingly. Is there a convention for GCR to be calculated using slant distance, maybe from the rooftop world?
I see the mathematical appeal of tracker limits being relative to the system plane, but I think the more common use case for nonzero side_slope is to still have Edit: gotta love having two github accounts and forgetting to switch between them... |
Thanks Kevin-NREL 😉
I think we can accommodate this, since we know the side slope then with
therefore in the backtracking condition becomes (existing algorithm):
or with #824, uses
Since you've worked for a developer, I defer to your judgment, but it would be very useful to get others to chime in here (@jforbess , @cwhanse , any others?). There may be flexibility to choose what we want if there is no existing convention, since trackers on terrain is kind of a newish concept. EG at SunPower I believe we assumed the sites were flat (or within 3-deg of flat which is nearly the same thing, |
I think we can do this too, just remove the 1st and last lines here. Perhaps we can consider if this is the best convention if there isn't yet a popular consensus.
In addition to the drive motor limits, I thought tracker rotation might be limited by the ground, if it's not high enough to rotate to 90° |
Agreed that input from others on conventions would be useful.
Good point. How about adding a new parameter
|
I'm not in favor of In either case, the rotation angle sign is referenced to the coordinate system described in the docstring. I had a conversation with a few people in the industry about conventions for rotation angle and azimuth - I heard a consensus that rotation of 0 degrees meant the module is horizontal, and negative rotation angle is generally thought of as the "morning" direction (east for N-S oriented trackers). As for whether a N-S tracker has azimuth 0 or 180, not a consensus. Currently, the rotation angle is viewed by looking in the direction of the tracker azimuth (positive y-axis in the coordinate system). In hindsight, I should have set a positive rotation as counter-clockwise about the y-axis, rather than positive being clockwise, to describe rotation as an angle. I was working too hard to maintain a connection to the reference (which assumes tracker azimuth points towards the equator) and also have negative rotation angles towards the east. |
Thanks Cliff!
I want to make sure this is completely clear, this PR does not change the rotation convention, and it uses the same algorithm as already exists in Regarding the Regarding adding a |
- by convention this is always defined relative to the zero-point rotation not the system-plane
I'm open to changing it so that rotations are angles in the usual sense, not in this PR's scope.
OK with me. |
OK, one more question. Is the GCR - is it based strictly on the horizontal distance between rows or not? EG:
Where:
|
I asked around some people I know in development engineering/performance engineering and 3/3 said that GCR is based on horizontal distance. N=3 isn't a great sample size, but some data is better than no data... Two thoughts:
|
Thanks! That makes a lot of sense. I'll ask around here, and see if people agree. Then I think it's okay to change gcr to horizontal. Then, will our two models will be the same? |
I still get one invalid warning here (from the older code): https://github.com/mikofski/pvlib-python/blob/6ed62ff68f9d6234c994274e8a92b22fc17e9bb5/pvlib/tracking.py#L607 Whatsnew entry for the new Otherwise good to merge from my perspective! 🚀 |
What's the rationale for #1041 as future work instead of deleting all the outdated and unneeded comments now? No comments is better than wrong comments. |
@wholmgren how much pruning is okay? Should I be greedy, conservative? Trust my instinct? |
I trust your instincts! |
* with new side_slope arg in SingleAxisTracker class * add fix for low sun angle tracker rotation calculations (issue 824) * add links to pr 823 * ignore invalid warnings for nan > x and nan % x in tracking.py
* remove commented code, especially any code relating to use of arctan2 adopted in 1fb82cc * remove comments that should be sourced directly from refernces, and instead list reference and Eqs. numbers * tidy up, combine lines, etc
OK maybe now? 🚀 |
I know I should shut my mouth, but is "tracker" redundant in Hopefully quick fix using rename symbols, better now than later, right? thanks! |
I agree |
* in api.rst * what's new v0.8.0 * tracking.py & test_tracking.py
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @kanderso-nrel let's rip that hairy bandaid off and consider this a wholesale replacement of pvlib.tracking
.
* side slope is line in system plane, perp. to tracker azimuth * clarify right handed rotation of side slope in example, also replace EG with "For example" * clarify comment defining the tracker coord-sys Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>
* use cross_axis_slope instead of side_slope * use calc_cross_axis_tilt() instead of calc_system_side_slope() * use slope azimuth & tilt instead of system az & ze * clarify cross-axis tilt is measured in the tracker reference frame * add cross-axis tilt to the SingleAxisTracker repr() * add see also to SingleAxisTracker * remove Lorenzo reference
OK, refactored names, clarified argument docstrings, and removed Lorenzo reference - hopefully you will all approve. Thanks.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there I think. This is a big lift and a significant improvement over the old tracker calculation.
* clarify cross-axis tilt by using consistent wording * use "tracker axes" when referring to tracker axes plane (or slope) instead of just "slope" * update SingleAxisTracker headline to refer user to singleaxis function * remove redundant wording in cross_axis_tilt arg, regarding tracker axes plane, and make it verbatim between SingleAxisTracker, singleaxis, and calc_cross_axis_tilt * improve links to module index in LocalizedSingleAxisTracker * Improve docstring for singleaxis to be explicit about right-handed coordinate system of tracker reference frame and right-handed rotation for tracker_theta * suggested changes to comments and do multiplication before division * change slope_tilt to be relative to horizontal rather than defined by normal, also use "tracker axes plane"
Hi All, thanks for your excellent comments and suggested edits. Where I've differed, my justification may have been hidden by resolving the conversation. Specifically here, here, and here. I want to restate my opinion that describing geometries and spatial orientations and rotations with words is very abstract, and IMHO there is no wording that will satisfy everyone b/c we all perceive them differently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kanderso-nrel wanna do the honors? |
Thanks @mikofski @kanderso-nrel and @cwhanse for this massive effort! @kanderso-nrel consider removing tracking.ipynb when you write the gallery example. |
N-S singleaxis trackers on an E-W slope
docs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
file for all changes.Brief description of the problem and proposed solution (more info in google groups post linked to above):
pvlib.tracking.calc_tracker_axis_tilt(system_azimuth, system_zenith, axis_azimuth) -> axis_tilt
pvlib.tracking.calc_system_tracker_side_slope(axis_azimuth, axis_tilt, system_azimuth, system_zenith) -> side_slope, relative_rotation
side_slope
topvlib.tracking.singleaxis
with default 0.Example 1: to model a N-S tracker on an east west slope, simple set axis tilt to zero, axis azimuth to 180, and system plane to (90, side slope), and set the side slope to what ever you want the E-W slope to be. Voila!
Example 2: you can model more complicated slopes in any direction.
(sys_az, sys_ze)
. this is the plane that contains the tracker axes.calc_tracker_axis_tilt
to back out the tracker axis tilt given its azimuthcalc_system_tracker_side_slope
to back out the slope perpendicular to the tracker axespvlib.tracking.singleaxis
with the calculated tracker axis tilt and side slope from steps 2 & 3Voila!