ソーラートラッカーの自作

横から見たソーラートラッカー

最近の高校では「総合的な探究の時間」というものがある. 実施される内容は学校ごとに違うらしいが, 通っていた学校は教育実験校でもあったため, 探究とは研究の真似事をする時間だった. そこで私がやった(似非)研究の要旨を, 情報としてまとめておく. 高校生が趣味の延長として探究した内容であるから, 研究とは受け取らないで, 優しい気持ちで読んでほしい1. 研究の経緯については別の記事に詳しい.

理論

順問題

太陽の方向と明るさがわかれば, (快晴かつ障害物の無い広い地表で, 大気を無視した場合,) 天球のある方向に向けた面の照度は計算で簡単に求めることができる.

太陽の方向を (θ,ϕ)(\theta_\odot, \phi_\odot), 面の法線の方向を (θ,ϕ)(\theta, \phi) とする. ただし, θ,ϕ\theta,\phi は球面座標におけるそれらと同義で, 角度を表わす. このとき, 太陽の方向と面の法線の方向がなす角を ψ\psi とすると,

cosψ=cosθcosθ+sinθsinθcos(ϕϕ)\cos \psi = \cos \theta_\odot \cos \theta + \sin \theta_\odot \sin \theta \cos (\phi_\odot - \phi)

であることが知られている2.

また, 太陽の(見かけの)光度を II とし, 太陽と面の距離を dd と置くと, 面の照度 EE は,

E=Id2cosψE = \frac{I}{d^2} \cos \psi

となることが知られている3.

ここで, 太陽と地球の距離は平均 1.5×1011m1.5 \times 10^{11} \, \mathrm{m} であり, 高校生にとってはとても長い距離であるから, dd は定数と見做すことができる. R=I/d2R = I/d^2 とおいて,

E=Rcosψ.E = R \cos \psi.

まとめると,

E(θ,ϕ)=R{cosθcosθ+sinθsinθcos(ϕϕ)}.E(\theta, \phi) = R \left\{ \cos \theta_\odot \cos \theta + \sin \theta_\odot \sin \theta \cos (\phi_\odot - \phi) \right\}.

逆問題

適当な方向に向けた複数の面の照度から, 太陽の光度と方向を求めることができる4.

n+1n+1 枚の面 (3n3 \leq n) について, 11 枚を天頂方向 (0,0)(0,0), nn 枚の面を (θ,2πk/n)(\theta, 2 \pi k / n) (kZ,0k<nk \in \mathbb{Z}, \, 0 \leq k < n) に向けたとして, それぞれの照度を Etop,E0,,En1E_\mathsf{top}, E_0, \dots, E_{n-1} とする. また, 順問題の E(θ,ϕ)E(\theta,\phi) の式に代入すると,

Etop=Rcosθ,Ek=R{cosθcosθ+sinθsinθcos(ϕ2πkn)}\begin{aligned} E_\mathsf{top} &= R \cos \theta_\odot, \\ E_k &= R \left\{ \cos \theta_\odot \cos \theta + \sin \theta_\odot \sin \theta \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right) \right\} \end{aligned}

という連立方程式が得られる.

ここで, E0,,En1E_0, \dots, E_{n-1} の平均を μ\mu, 標準偏差を σ\sigma とおくと,

μ=1nk=0n1Ek=1nk=0n1R{cosθcosθ+sinθsinθcos(ϕ2πkn)}=Rcosθcosθ,σ2=1nk=0n1(Ekμ)2=1nk=0n1{Rsinθsinθcos(ϕ2πkn)}2=12R2sin2θsin2θ.\begin{aligned} \mu &= \frac{1}{n} ∑^{n-1}_{k=0} E_k \\ &= \frac{1}{n} ∑^{n-1}_{k=0} R \left\{ \cos \theta_\odot \cos \theta + \sin \theta_\odot \sin \theta \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right) \right\} \\ &= R \cos \theta_\odot \cos \theta, \\ \sigma^2 &= \frac{1}{n} ∑^{n-1}_{k=0} (E_k - \mu)^2 \\ &= \frac{1}{n} ∑^{n-1}_{k=0} \left\{ R \sin \theta_\odot \sin \theta \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right) \right\}^2 \\ &= \frac{1}{2} R^2 \sin^2 \theta_\odot \sin^2 \theta. \end{aligned}

となる. ただし, k=0n1cos(ϕ2πk/n)=0∑^{n-1}_{k=0} \cos \left(\phi_\odot - 2 \pi k / n \right) = 0, k=0n1cos2(ϕ2πk/n)=n/2∑^{n-1}_{k=0} \cos^2 \left(\phi_\odot - 2 \pi k / n \right) = n/2 であることを用いた(証明は省略).

まとめて,

Etop=Rcosθ,μ=Rcosθcosθ,2σ=Rsinθsinθ.\begin{aligned} E_\mathsf{top} &= R \cos \theta_\odot, \\ \mu &= R \cos \theta_\odot \cos \theta, \\ \sqrt{2} \, \sigma &= R \sin \theta_\odot \sin \theta. \end{aligned}

θ\theta_\odot について解いて,

θ=arg(Etopμ1cosθ+2σsinθj).\theta_\odot = \underline{ \arg \left( \frac{E_\mathsf{top} - \mu}{1 - \cos \theta} + \frac{\sqrt{2} \sigma}{\sin \theta} \, j \right)}.

また, EkE_k に代入して,

Ek=2σcos(ϕ2πkn)+μ.E_k = \sqrt{2} \sigma \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right) + \mu. Ekμ2σ=cos(ϕ2πkn).\frac{E_k - \mu}{\sqrt{2} \sigma} = \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right).

ここで,

L=k=0n1{Ekμ2σcos(ϕ2πkn)}2L = ∑^{n-1}_{k=0} \left\{ \frac{E_k - \mu}{\sqrt{2} \sigma} - \cos \left(\phi_\odot - \frac{2 \pi k}{n} \right) \right\}^2

とおき, LL を最小化する ϕ\phi_\odot を求める(最小二乗法). 右辺を展開して,

L=n22+k=0n1(Ekμ)22σ22σ(cosϕk=0n1Ekcos2πkn+sinϕk=0n1Eksin2πkn).L = \frac{n^2}{2} + ∑^{n-1}_{k=0} \frac{(E_k - \mu)^2}{2 \sigma^2} - \frac{\sqrt{2}}{\sigma} \left( \cos \phi_\odot ∑^{n-1}_{k=0} E_k \cos \frac{2 \pi k}{n} + \sin \phi_\odot ∑^{n-1}_{k=0} E_k \sin \frac{2 \pi k}{n} \right).

第3項の括弧内を最大化すればいいから,

ϕ=arg(k=0n1Ekcos2πkn+jk=0n1Eksin2πkn).\phi_\odot = \underline{ \arg \left( ∑^{n-1}_{k=0} E_k \cos \frac{2 \pi k}{n} + j ∑^{n-1}_{k=0} E_k \sin \frac{2 \pi k}{n} \right)}.

無知な高校生にはここまでしかできなかったが, ベクトル解析あたりを用いればもっとスマートに解けるかもしれない. 「今後の課題」欄が捗る解である.

実装

逆問題の解を実装した装置を作った.

ソーラートラッカー

マイコンにはSTM32F303K8を使い, 12ビットのADCで 3+13+1 個の照度センサ(NJL7302)の光電流を計測している. ソースコードはこれ.

逆問題の計算部分は,

  1. まず μ\muσ\sigma を計算.
// 以下, https://github.com/xiupos/solar-tracker/blob/main/src/main.cppより抜粋
temp_mu = (val_ee + val_nw + val_sw) / 3;
temp_sg = sqrt(
    (val_ee - temp_mu) * (val_ee - temp_mu) +
    (val_nw - temp_mu) * (val_nw - temp_mu) +
    (val_sw - temp_mu) * (val_sw - temp_mu)
  );
  1. (Etopμ)/(1cosθ)(E_\mathsf{top} - \mu)/(1 - \cos \theta)2σ/sinθ\sqrt{2} \sigma / \sin \theta を計算して, atan2(sin,cos) で偏角 θ\theta_\odot を求める.
temp_cos = (val_tp - temp_mu) / (1 - COS_TH);
temp_sin = (SQRT_2 * temp_sg) / SIN_TH;
temp_theta = RAD2DEG(atan2(temp_sin, temp_cos));
  1. k=0n1Ekcos(2πk/n)∑^{n-1}_{k=0} E_k \\cos (2 \pi k / n)k=0n1Eksin(2πk/n)∑^{n-1}_{k=0} E_k \sin (2 \pi k / n) を計算して, atan2(sin,cos) で偏角 ϕ\phi_\odot を求める.
temp_cos = val_ee * COS_000 + val_nw * COS_060 + val_sw * COS_120;
temp_sin = val_ee * SIN_000 + val_nw * SIN_060 + val_sw * SIN_120;
temp_phi = RAD2DEG(atan2(temp_sin, temp_cos));

という具合に組込める. 大抵の言語で複素数の偏角を求める関数があると思うので, 汎用性は高いと思ってる.

上部のサーボ(2軸)で太陽の方向を指し示すようにしているが, 概ね方向は合っていると思う5.

応用

元々は太陽光発電用ソーラートラッカーを作る研究だった. 他には, 探査機が自分の位置を測ることなどに応用できると思う. たぶんもうやらないが.

Footnotes

  1. もちろん立派な研究をする高校生もいる. おならの匂いを消すパンツを作り話題になった先輩など.

  2. これを球面三角法の余弦定理という. 古くは航海術の時代に使われていたらしい.

  3. Beleuchtungsstärke – Wikipedia, 光学 講義ノート 黒田和男(第10章 測光・測色).

  4. ここでの適当は「適切な方向で」という意味で, 任意の数の面だったり, 解が存在する条件だったりは証明できていない.

  5. 研究であれば厳密な検証が必要だろうが, 4個の照度センサだけではどうしても限界があるので目を瞑ってほしい.