{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nSingle-axis tracking\n====================\n\nExamples of modeling tilt angles for single-axis tracker arrays.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This example shows basic usage of pvlib's tracker position calculations with\n:py:meth:`pvlib.tracking.singleaxis`.  The examples shown here demonstrate\nhow the tracker parameters affect the generated tilt angles.\n\nBecause tracker angle is based on where the sun is in the sky, calculating\nsolar position is always the first step.\n\nTrue-tracking\n-------------\n\nThe basic tracking algorithm is called \"true-tracking\". It orients the panels\ntowards the sun as much as possible in order to maximize the cross section\npresented towards incoming beam irradiance.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import solarposition, tracking\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\ntz = 'US/Eastern'\nlat, lon = 40, -80\n\ntimes = pd.date_range('2019-01-01', '2019-01-02', closed='left', freq='5min',\n                      tz=tz)\nsolpos = solarposition.get_solarposition(times, lat, lon)\n\ntruetracking_angles = tracking.singleaxis(\n    apparent_zenith=solpos['apparent_zenith'],\n    apparent_azimuth=solpos['azimuth'],\n    axis_tilt=0,\n    axis_azimuth=180,\n    max_angle=90,\n    backtrack=False,  # for true-tracking\n    gcr=0.5)  # irrelevant for true-tracking\n\ntruetracking_position = truetracking_angles['tracker_theta'].fillna(0)\ntruetracking_position.plot(title='Truetracking Curve')\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Backtracking\n-------------\n\nBecause truetracking yields steep tilt angle in morning and afternoon, it\nwill cause row to row shading as the shadows from adjacent rows fall on each\nother. To prevent this, the trackers can rotate backwards when the sun is\nnear the horizon -- \"backtracking\".  The shading angle depends on row\ngeometry, so the gcr parameter must be specified.  The greater the gcr, the\ntighter the row spacing and the more aggressively the array must backtrack.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, ax = plt.subplots()\n\nfor gcr in [0.2, 0.4, 0.6]:\n    backtracking_angles = tracking.singleaxis(\n        apparent_zenith=solpos['apparent_zenith'],\n        apparent_azimuth=solpos['azimuth'],\n        axis_tilt=0,\n        axis_azimuth=180,\n        max_angle=90,\n        backtrack=True,\n        gcr=gcr)\n\n    backtracking_position = backtracking_angles['tracker_theta'].fillna(0)\n    backtracking_position.plot(title='Backtracking Curve',\n                               label='GCR:{:0.01f}'.format(gcr),\n                               ax=ax)\n\nplt.legend()\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}