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

最近の高校では「総合的な探究の時間」というものがある.
実施される内容は学校ごとに違うらしいが,
通っていた学校は教育実験校でもあったため,
探究とは研究の真似事をする時間だった.
そこで私がやった(似非)研究の要旨を,
情報としてまとめておく.
高校生が趣味の延長として探究した内容であるから,
研究とは受け取らないで, 優しい気持ちで読んでほしい1.
研究の経緯については別の記事に詳しい.
理論
順問題
太陽の方向と明るさがわかれば,
(快晴かつ障害物の無い広い地表で, 大気を無視した場合,)
天球のある方向に向けた面の照度は計算で簡単に求めることができる.
太陽の方向を (θ⊙,ϕ⊙),
面の法線の方向を (θ,ϕ) とする.
ただし, θ,ϕ は球面座標におけるそれらと同義で, 角度を表わす.
このとき, 太陽の方向と面の法線の方向がなす角を ψ とすると,
cosψ=cosθ⊙cosθ+sinθ⊙sinθcos(ϕ⊙−ϕ)
であることが知られている2.
また, 太陽の(見かけの)光度を I とし,
太陽と面の距離を d と置くと,
面の照度 E は,
E=d2Icosψ
となることが知られている3.
ここで, 太陽と地球の距離は平均 1.5×1011m であり,
高校生にとってはとても長い距離であるから, d は定数と見做すことができる.
R=I/d2 とおいて,
E=Rcosψ.
まとめると,
E(θ,ϕ)=R{cosθ⊙cosθ+sinθ⊙sinθcos(ϕ⊙−ϕ)}.
逆問題
適当な方向に向けた複数の面の照度から,
太陽の光度と方向を求めることができる4.
n+1 枚の面 (3≤n) について, 1 枚を天頂方向 (0,0),
n 枚の面を (θ,2πk/n) (k∈Z,0≤k<n)
に向けたとして,
それぞれの照度を Etop,E0,…,En−1 とする.
また, 順問題の E(θ,ϕ) の式に代入すると,
EtopEk=Rcosθ⊙,=R{cosθ⊙cosθ+sinθ⊙sinθcos(ϕ⊙−n2πk)}
という連立方程式が得られる.
ここで, E0,…,En−1 の平均を μ, 標準偏差を σ とおくと,
μσ2=n1k=0∑n−1Ek=n1k=0∑n−1R{cosθ⊙cosθ+sinθ⊙sinθcos(ϕ⊙−n2πk)}=Rcosθ⊙cosθ,=n1k=0∑n−1(Ek−μ)2=n1k=0∑n−1{Rsinθ⊙sinθcos(ϕ⊙−n2πk)}2=21R2sin2θ⊙sin2θ.
となる. ただし,
∑k=0n−1cos(ϕ⊙−2πk/n)=0,
∑k=0n−1cos2(ϕ⊙−2πk/n)=n/2
であることを用いた(証明は省略).
まとめて,
Etopμ2σ=Rcosθ⊙,=Rcosθ⊙cosθ,=Rsinθ⊙sinθ.
θ⊙ について解いて,
θ⊙=arg(1−cosθEtop−μ+sinθ2σj).
また, Ek に代入して,
Ek=2σcos(ϕ⊙−n2πk)+μ.
2σEk−μ=cos(ϕ⊙−n2πk).
ここで,
L=k=0∑n−1{2σEk−μ−cos(ϕ⊙−n2πk)}2
とおき, L を最小化する ϕ⊙ を求める(最小二乗法).
右辺を展開して,
L=2n2+k=0∑n−12σ2(Ek−μ)2−σ2(cosϕ⊙k=0∑n−1Ekcosn2πk+sinϕ⊙k=0∑n−1Eksinn2πk).
第3項の括弧内を最大化すればいいから,
ϕ⊙=arg(k=0∑n−1Ekcosn2πk+jk=0∑n−1Eksinn2πk).
無知な高校生にはここまでしかできなかったが,
ベクトル解析あたりを用いればもっとスマートに解けるかもしれない.
「今後の課題」欄が捗る解である.
実装
逆問題の解を実装した装置を作った.

マイコンにはSTM32F303K8を使い,
12ビットのADCで 3+1 個の照度センサ(NJL7302)の光電流を計測している.
ソースコードはこれ.
逆問題の計算部分は,
- まず μ と σ を計算.
// 以下, 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)
);
- (Etop−μ)/(1−cosθ) と
2σ/sinθ を計算して,
atan2(sin,cos)
で偏角 θ⊙ を求める.
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));
- ∑k=0n−1Ekcos(2πk/n) と
∑k=0n−1Eksin(2πk/n) を計算して,
atan2(sin,cos)
で偏角 ϕ⊙ を求める.
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.
応用
元々は太陽光発電用ソーラートラッカーを作る研究だった.
他には, 探査機が自分の位置を測ることなどに応用できると思う.
たぶんもうやらないが.