@@ -303,35 +303,44 @@ RC PVARRAY::pv_CalcPOA()
303303 {
304304 case C_PVARRCH_1AXT:
305305 {
306- float sinz = sin (acos (cosz));
307- float x = (sinz*sin (azm - pv_azm)) / (sinz*cos (azm - pv_azm)*sin (pv_tilt) + cosz*cos (pv_tilt));
308- float psi;
309- if (x < 0 .f && (azm - pv_azm) > 0 .f ) {
306+ // Based on Rotation Angle for the Optimum Tracking of One-Axis Trackers by William F.Marion and Aron P.Dobos
307+ const float sinz = sin (acos (cosz)); // sin of zenith angle
308+ float azm_delta = azm - pv_azm;
309+
310+ // normalize azm_delta between -Pi and Pi
311+ if (azm_delta >= kPi )
312+ azm_delta = azm_delta - k2Pi;
313+
314+ if (azm_delta <= -kPi )
315+ azm_delta = azm_delta + k2Pi;
316+
317+ const float x = (sinz*sin (azm_delta)) / (sinz*cos (azm_delta)*sin (pv_tilt) + cosz*cos (pv_tilt)); // from Equation #7
318+ float psi = 0 .f ;
319+
320+ if (x < 0 .f && azm_delta > 0 .f ) {
310321 psi = kPi ;
311322 }
312- else if (x > 0 .f && (azm - pv_azm) < 0 .f ){
323+ else if (x > 0 .f && azm_delta < 0 .f ){
313324 psi = -kPi ;
314325 }
315- else {
316- psi = 0 .f ;
317- }
318- float r = atan (x) + psi;
326+
327+ pv_panelRot = atan (x) + psi; // Equation #7
328+
319329 const float rlim = 0 .25f *kPi ;
320- r = max (-rlim, min (rlim, r ));
321- pv_panelTilt = acos (cos (r )*cos (pv_tilt));
330+ pv_panelRot = max (-rlim, min (rlim, pv_panelRot ));
331+ pv_panelTilt = acos (cos (pv_panelRot )*cos (pv_tilt)); // Equation #1
322332 if (pv_panelTilt == 0 .f ) {
323333 pv_panelAzm = pv_azm;
324334 }
325335 else
326336 {
327- float rx = bracket (-1 .f , sin (r) / sin (pv_panelTilt), 1 .f );
328- float asrx = asin (rx);
329- if (r >= -kPiOver2 && r <= kPiOver2 )
330- pv_panelAzm = pv_azm + asrx;
331- else if (r >= -kPi && r < -kPiOver2 )
332- pv_panelAzm = pv_azm - asrx - kPi ;
333- else // if (r > kPiOver2 && r <= kPi)
334- pv_panelAzm = pv_azm - asrx + kPi ;
337+ float const asrx = asin (bracket (-1 .f , sin (pv_panelRot) / sin (pv_panelTilt), 1 .f ));
338+ if (pv_panelRot >= -kPiOver2 && pv_panelRot <= kPiOver2 )
339+ pv_panelAzm = pv_azm + asrx; // Equation #2
340+ else if (pv_panelRot >= -kPi && pv_panelRot < -kPiOver2 )
341+ pv_panelAzm = pv_azm - asrx - kPi ; // Equation #3
342+ else // if (pv_panelRot > kPiOver2 && pv_panelRot <= kPi)
343+ pv_panelAzm = pv_azm - asrx + kPi ; // Equation #4
335344 }
336345 }
337346 break ;
0 commit comments