並列接続
もう先月の事になるけど、友人が暑さしのぎで近くの図書館に避難してたそうだ。それって、 中国の人が避暑で地下鉄の構内やらIKEAの売り場(ちゃっかり、展示物のベットやらソファーで 寛いでいた)に押しかけて、社会問題になっていたような。 まあ、クールをシェアしましょって何処かのお役所が推奨してたから、友人は模範的国民認定。
で、目の前に大量に有る雑誌やら図書をとりとめもなく眺めていたそうな。太陽光パネルの 落とし穴なんてのを手にしたら、面白い事が書かれていたってわざわざ教えてくれた。
カタログに載っている発電効率は、25℃でのものらしい。温度が1℃上がると0.5%だかづつ 低下してくらしい。炎天下のパネルなら、60度とか平気で行くだろう。仮に65℃とすれば、 カタログでの温度より40℃高いので、効率20%低下の計算になる。
パネルは、8枚ぐらい直列にして電圧を上げた状態で取り出す。電池の直列接続と一緒。 どれかのパネルに影とかが当たると、そのパネルの出力能力は低下する。直列にしたパネルの 出力能力も、低いパネルに足を引っ張られて低下する。なかなか、カタログ通りにはいかない 現実が待っているとか。
発電した電力は、東京電力なりへ売電して儲ける事を企む。直流の高電圧をインバーターで 交流に変換して、位相を合わせて、送電網へ送り出す。この時、東電からの電圧よりも、2 ないし3V高めにして、太陽電池の電力をねじ込む形になる。
で、どのぐらいの電力を供給してるかメーターで確認出来るそうなんだけど、これって回路網の 解析で解けるのかな。回路解析の基本は、キルヒホッフの法則だな。
東電側の電圧を、Et。出力抵抗をRt。負荷をRl(ご近所さんちの電球とかトースターです)とすると。その直列回路になるな。 太陽光側の電圧を、Es。その出力抵抗をRsとして、その回路がRlに接続される(要するに、負荷をシェアする)等価回路か。
負荷に流れる電流をIlとし、東電側からの供給をIt、太陽光側からの電流をIsとする。 求めたいのは、Isだ。図にすると、下記のようになるかな。2つの電源の接続点は、aになり、 負側は、負荷も含めて、共通だ。
Is Rs +----<----/\/\/\-----+[ Es ]-------+ | Il Rl | a +---->---------/\/\/\/\------------+ | | +----<----/\/\/\-----+[ Et ]-------+ It Rt
(円記号は心の中でバックスラッシュに置き換えてください。ほーら、抵抗の回路記号に 思えてきたでしょ。それから、電池の記号はオイラーの発明です。あしからず。)
It + Is = Il 負荷に流れる電流は、第一法則が適用される(a点での電流の関係) Et = It*Rt + Il*Rl 東電側の閉回路、 第二法則を適用 Es = Is*Rs + Il*Rl 太陽光側の閉回路、 第二法則を適用
これで、3元1次方程式が出来上がった。後は、紙の上で、式を変形していけばいいんだけど、 ずばりを求めるのではなく、パラメータが入った形(記号的)で求めたい。Wolframの登場か? いいえ、 手元で計算させます。Debianに、こんな事もあろうかと、wxmaximaを入れておいたのさ。 今回はそのCUI版です。
deb9:~$ maxima Maxima 5.38.1 http://maxima.sourceforge.net using Lisp GNU Common Lisp (GCL) GCL 2.6.12 (%i1) eq1: It + Is = Il; (%o1) It + Is = Il (%i2) eq2: Et = It*Rt + Il*Rl; (%o2) Et = It Rt + Il Rl (%i3) eq3: Es = Is*Rs + Il*Rl; (%o3) Es = Is Rs + Il Rl (%i4) linsolve( [eq1,eq2,eq3], [Is,It,Il] ); Es Rt + (Es - Et) Rl Et Rs + (Et - Es) Rl (%o4) [Is = --------------------, It = --------------------, (Rs + Rl) Rt + Rl Rs (Rs + Rl) Rt + Rl Rs Es Rt + Et Rs Il = --------------------] (Rs + Rl) Rt + Rl Rs
普通は、solve関数を使うようなのですが、連立式用の関数もあるようです。Isだけ求めようと したら、解無しになったので、全てを求めています。電圧差が有る程、東電側に電力を沢山 売れる訳だな。
もう少し式を吟味すると、分母側でえこひいきがありそう。CP対称性の破れでノーベル賞を 貰ったあの先生の気分。分母側の式が美しくないぞ。(回路が対称なんだから、共通な分母は、変数の表れ方に対称を期待)後で徹底調査だな。
なお、キルヒホッフなんて突然だったので、下記をパクらせていただきました。 http://www.asahi-net.or.jp/~jk2m-mrt/reidai_2.htm これって、直流でも交流でも成り立つよね。(今頃言ってどうする)
Maxima a Computer Algebra System
検算
上記の記号的な求解が合っているか、他のプラットフォームで検算してみる。目を付けたのは OpenBSD。こいつのports/mathの中に制作仕様書が有ったので、どんな付属品が必要か確認。 Makefileにこんな必要品が列挙されてた。
WANTLIB += c ecl ffi gc gmp m pthread
maximaと共に新たにやって来るのは、eclっていう、 組み込み用のLispぐらいだろう。Debianでは、湯浅先生とその仲間が京都大学時代に開発して 世界を驚かしたKCLが使われていたからね。(その後、KCLはGNUに寄贈されてGCLになった。)
予想通り、eclと共にmaximaがやって来た。
$ maxima ;;; Loading #P"/usr/local/lib/ecl/sb-bsd-sockets.fas" ;;; Loading #P"/usr/local/lib/ecl/sockets.fas" ;;; Loading #P"/usr/local/lib/ecl/defsystem.fas" ;;; Loading #P"/usr/local/lib/ecl/cmp.fas" Maxima 5.39.0 http://maxima.sourceforge.net using Lisp ECL 16.1.3 (%i1) solve( [Rl*(Is+It) + Rt*It = Et, Rl*(Is+It) + Rs*Is = Es], [Is,It]); Es Rt + (Es - Et) Rl Et Rs + (Et - Es) Rl (%o1) [[Is = --------------------, It = --------------------]] (Rs + Rl) Rt + Rl Rs (Rs + Rl) Rt + Rl Rs
今度は、solve関数で求めてみる。キルヒホッフの第一法則では、負荷回路に流れる電流は、 東電側からのやつと太陽光側が発電したものの合計だよって言ってるので、素直に置き換えて 元数を一つ下げてある。答えは一致してたね。良かった良かった。
まてまて、プラットフォームが異なっても、所詮同じ穴のムジナ。上記のような態度じゃ、 検算した事にはならないだろう! だったら、Wolframさんの所へ行って、検算してくるかい? Wolframさんって、天才な人なのね。 マセマティカを作った男 恐れ多くて、近づけませんよ。
そんな訳で、3秒考えて、久しぶりにPythonです。 Sympy : Python での代数計算なんて事が出来ますからね。
まず、使う記号を登録するようです。
>>> from sympy import * >>> Es, Et = symbols('Es Et') >>> Is, It = symbols('Is It') >>> Rs, Rt, Rl = symbols('Rs Rt Rl') >>> solve([Rl*(Is+It) + Rt*It = Et, Rl*(Is+It) + Rs*Is = Es], [Is, It]) File "<stdin>", line 1 solve([Rl*(Is+It) + Rt*It = Et, Rl*(Is+It) + Rs*Is = Es], [Is, It]) ^ SyntaxError: invalid syntax
そして、走らせたら、見事に文句を言われました。式の中で、= は、使えないようです。と 言うか、式の値はZEROと見做して計算されるそうです。
だったら、電圧源を移項しちゃえ。そう、これこそがキルヒホッフの第二法則を表して いるんです。回路を一回りした時の電圧差はZEROであるってね。
ちなみに、第一法則ってのは、ある接点に流れ込む電流の総和と流れ出す電流の総和はこれまた ZEROであるってのです。(電子回路では、流れ込む電流をプラス、流れ出す電流をマイナスに する約束です。)これも、最初に建てた式の項を移項すれば、右辺はZEROになる。
In [2]: solve([Rl*(Is+It) + Rt*It - Et, Rl*(Is+It) + Rs*Is - Es], [Is, It]) Out[2]: {Is: (-Es*(Rl + Rt) + Et*Rl)/(Rl**2 - (Rl + Rs)*(Rl + Rt)), It: (Es*Rl - Et*(Rl + Rs))/(Rl**2 - (Rl + Rs)*(Rl + Rt))}
ipythonも入っているのを忘れていたので、シンボルの登録部分を%cpasteしてから、計算 させてみた。
今度は、文句も言われずに計算してくれました。ちょっと見にくいので、Isだけを 見やすく整理してみます。
Et*Rl - Es*(Rl + Rt) Is = --------------------------- Rl**2 - (Rl + Rs)*(Rl + Rt)
この方が分母の部分が対称で美しいと思うぞ。それにしても使う道具によって結果が異なると 凡人は、右往左往しちゃうぞ。ここはもう、サード・オピニオンと言うか、第三者に判定を 委ねるしかないか。
こういう時に、政府は自分の都合が良い委員を選んで、お茶を濁すのが 常です。でも、オイラーはそんな邪な考えなんて一切ありません。天才と誉高い人に権威付け してもらうのが良いでしょう。(言っとくけど、袖の下とか、アンダー・ザ・テーブルなんて のはありませんです。)
Wolframさんの所で、下記の式を入力。カッコの扱い等が、世間一般と違うので戸惑う。 そして、変数名も一文字っぽくて、あらかじめ用途が決まってるのもあるっぽい。 (電圧は三相交流回路によく出て来る、u,v,wを真似てu,vに、出力抵抗は一般的な定数を思い出してa,bに、負荷はrに、電流はx,yにそれぞれ置き換えている)
solve [ r{x+y} + ax == u && r{x+y} + by == v, {x,y} ]
結果が出てきたけど、いろんな条件を付けられてしまって、何が何だかよく分からん。 分母がZEROで無い、かつbもZEROじゃ無いと言う制限が付いているのを見ればいいのか。
b u + r (u - v) x = ----------------- a (b + r) + b r
これを、脳内パターンマッチすれば、天才の出した答えとmaximaが出した答えが一致してる 事が確認出来た。よって、多数決の原理で、パイソンの負けが決定しました。誰か、筆算で 検算してください。オイラーは、そんな元気有りませんです。だったら、上でさりげなく紹介してる、数の帝国へ行け。記号でもちゃんと解いてくれるぞ。
ああ、関数の入力がどんな値でも答えを持つ、全域関数と、特定な入力で関数の結果が未定義に なる、部分関数ってのが有るんだった。Haskellの本を読んでいたら、そんな事が書いてあったぞ。
って、事で、再びHaskellに戻ります。一つの投稿に複数の事項を載せるのは、ググル様が 嫌う事ですが、長年の癖が染み付いていますので、勘弁勘弁。
考察
ここまでやっておいて、放り出してしまっていいのかと、(元)技術者の声が、心の底から 聞こえてきた。
単に式を建てて、道具を使って計算させただけじゃない。日本の大学では、こういう計算には mathmaticaなんて道具は絶対に使うな。ねじり鉢巻きで汗水たらして筆算でやれって 指導されてるとか。欧米では、便利な道具を使わないのは罪って事で、使う事を推奨してる らしい。
そして、余裕を持って、意味を考えるんだろうね。そうしなきゃ罪だとオイラーも思うぞ。
まず分母の整理だな。一番最初に出てきた式を利用しよう。(負荷抵抗は、両電源に対して 共通なので、R の記号を使う事にする。
(Rs + R) Rt + R Rs = Rt Rs + R Rt + R Rs = R (Rt + Rs) + Rt Rs = Z
じっと見てたら、電気屋さんぽく整理出来る事に気付いた。見かけでころっと騙されてしまったみたい。展開してから新たにRで括り出した。道具だとこういう風に意図を持った変形は望むべくじゃないな。裏でAIが 動いていても、こういう事はやってくれないだろうな。
次は分子の方。2項になってるので、分解してみる。
Is = (Es Rt / Z) + ((Es - Et) R / Z) It = (Et Rs / Z) + ((Et - Es) R / Z) I = (Es Rt / z) + (Et Rs / Z)
Is と It の第2項目は、電圧の極性が逆なんで、相殺されてしまうから、負荷回路には寄与 しない。けど、これって電源間でやり取りされている事になる。無駄電流である。
無駄電流は、電圧に差が無いと発生しない。負荷が軽い程(Rが大きい程)顕著になる。 その極限は、Rが極めて大きい時(極端な場合は、負荷抵抗が無い場合)となる。電源同士が 喧嘩する場合だ。
何気なく、極限なんて言葉を使ってしまったけど、maximaにも極限って関数が有るよ。 ああ、その前に数学での記号は、limだな。これに下付きで、x -> 0 とか、x -> ∞ とか が付くんだった。式の中のxがZEROまで行ったらとか、逆にxが無限大まで振れたらとかの 説明が付くのだった。
早速やってみる。Isを表す式中のR(負荷抵抗)が、無限大(inf)になった場合を計算 してもらえばいいのだ。
(%i8) limit((Es*Rt + (Es-Et)*R) / (R*(Rs+Rt) + Rs*Rt), R, inf); Et - Es (%o8) - ------- Rt + Rs
経験値が、数式で示された。って、普通に考えたらこうならざるを得ない。負荷が無限大 なら無いのと一緒、だから取り外してしまえと、回路図を簡約化すればいいわけですね。
頭にマイナス記号が付いているのは気にしない。単に電流の方向を表しているだけですから。
(%i9) limit((Es*Rt + (Es-Et)*R) / (R*(Rs+Rt) + Rs*Rt), R, 0); Es (%o0) -- Rs
おまけで、負荷抵抗がショートした場合にどうなるか、計算させてみた。ショートって事は、 抵抗値がZEROね。電池の内部抵抗は非常に小さいので、膨大な電流が流れる事になる。
努々、電池はショートさせないようにね。発熱して爆発するぞ。実際の値はどのぐらい? 実験した人が居た。 電池の性能って結構違うんですよ?
小学生の高学年だかで、電池の直列接続と並列接続について習うと思う。豆電球か何かを 回路につなげて、直列の場合は明るく点きますねー。でも長続きしないよ。 それに対して、並列接続だと、(直列に比べて)ずっと長く電球が光りますって、やったと 思う。
並列接続の場合は、電池の特性が一致したものを使わないと、上記で見たように、電池間で 電流が流れてしまって、いつの間には電池が減ってしまう原因になりかねない。
電池を3本並列に使うような機器(今までの経験だと、そんなの余り無いけど)で、電池が 減ったから3本を取り換えようとした場合、一本はパッケージに残っていた電池を使い、2本は別のパッケージから補充、、、なんて事をしてはいけません。
パッケージが別だと、あるいはメーカーが異なる等の場合、特性がバラバラで、無駄に 電流が流れてしまう確率が高くなります。台風シーズンに備えて注意しましょう。
数学ドリル
上でちらっと出てきた、分母の整理。これって、数学で言う、式の展開と整理だ。 整理って、突き詰めていくと、直和にするか直積にするかの世界になる。
たとえば、6って数字を、整数の範囲で2つに分解しなさいって問題。
x + y = 6 x * y = 6
上式が、直和。下式が直積になる。直和では、組み合わせが無限になる。直積の方は、組み合わせが限定される。直積の方が数学的にはずっと扱い易く、使い道も直和に比べて多い。
直積で組み立てる数字に素数だけを使うとすると、素因数分解って事になる。
これ以上ないと言うぐらい、優しい求め方が出てた。maximaでやっても易しいね。
(%i1) factor(360); 3 2 (%o1) 2 3 5
それじゃ、素因数分解と親戚の因数分解を調べてみる。こちらは、式を対象にするものだ。
受験対策だな。因数分解出来て何が嬉しいなんて事は、何も書いてない。まあ、これだけを 見て、けなすのはフェアーじゃない事は、承知してますがね。
(%i2) factor(3*x^2 + 10*x + 7); (%o2) (x + 1) (3 x + 7)
この例だと、2次方程式(右辺はZEROを仮定するので省略されてる)の根(答え)が一発で 求められるというのが、特典です。式を因数分解しても右辺は相変わらずZERO。何かと 何かを掛け算してZEROになるためには、どちらかの何かがZEROであれば良い。直積の 効能が発揮された瞬間。
(%i8) factor(3*x^2 - 7*x - 23); 2 (%o8) 3 x - 7 x - 23
でも、式によっては、因数分解出来ない、いじわるな奴もいるよ。困ったものだ。こういう場合は、gnuplotか何かで、グラフを書かせて、X軸とグラフの交点を読み取る、視覚法が便利。 (二次方程式の根を求める式を思い出してもいいけど、5次方程式の根を求める公式なんて、 思い出せるか? それより、そんな公式有ったっけ?)
マニュアル見てたら、そのものずばりの根を求めるってのが用意されてた。
(%i9) f(x) := 3*x^2 - 7*x - 23; 2 (%o9) f(x) := 3 x - 7 x - 23 (%i10) find_root(f, 0,10); (%o10) 4.171292729553325
求めたい式を登録。そして、その式の探索範囲を指定すると、根を探してくれる。
(%i12) find_root(f, -5,10); find_root: function has same sign at endpoints: f(- 5.0) = 87.0, f(10.0) = 207.0 -- an error. To debug this try: debugmode(true);
でも、万能じゃないので、範囲の与え方を間違うと、だめだと言われる。人工知能を組み込んで 欲しいな。裏でLispが動いているんでしょ。
ああ、そうそう、裸のmaximaだと、以前入力したデータを修正して実行ってのが出来ないので、 rlwrapと組み合わせると便利。emacsから使えるようにも出来るけど、ちと大げさ過ぎる。
limitが出てきたので、有名な使い方を思い出したぞ。
(%i5) limit( ((x+h)^4 - x^4) / h, h, 0); 3 (%o5) 4 x (%i6) limit( (sin(x+h) - sin(x))/h ,h,0); (%o6) cos(x)
xの4乗やsin(x)を、定義通りに、微分してみた。
実際のインバーター
上で解析したように、パネル側で作った電圧と、東電側からの電圧が等しければ、電源間に 余分な(闇)電流が流れない。それなのに、実際はパネル側が数ボルト高い電圧を出してる そうだ。何故?
これはもう、実際の回路に当たるしかないだろう。
上に挙げたのは、東電に接続しないタイプのもの。秋葉原あたりに行けば、既製品が簡単に 手に入ると思われる。
それに対して、東電に接続するような奴は、プロが設計・製作・試験したやつじゃないと、 技術的にも法律的にも無理。細かい事は企業秘密になるだろう。
太陽光発電システム用大容量パワーコンディショナのミニモデルを用いた試験方法
もっと丹念に探さないと、見つからないかな?
ASCII ART
emacsで図を書こうとすると、picture-modeってのが便利だ。
だが、図の中に文字とかを書き込むと、それらが追加されちゃって図が崩れる(場合が有る)。こういう時は、 overwriteで、切り替えればよい。
余り図を入れるって事はないから、これぐらい知ってればいいだろう。
職人になるなら、
アスキーアート (ASCII ART) をコマンドラインで楽しむ3つの方法
とかかな。
debian:~$ echo hello world | boxes -d cat /\ /\ |`\\_,--="=--,_//`| \ ." :'. .': ". / ==) _ : ' : _ (== |>/O\ _ /O\<| | \-"~` _ `~"-/ | >|`===. \_/ .===`|< .-"-. \===' | '===/ .-"-. .---{'. '`}---\, .-'-. ,/---{.'. '}---. ) `"---"` `~-===-~` `"---"` ( ( hello world ) ) ( '---------------------------------------'
rlwrap のちょっと便利な技
maximaを使う時、rlwrapと組み合わせると、既入力を編集出来て便利って書いた。 なにげにrlwrapのヘルプを見てたら、ログが取れるよと書いてあったぞ。 試してみる。
$ rlwrap -l LOG maxima
セッションがしっかり記録されてた。
$ cat LOG : (%i1) ?? 0: Airy Functions 1: Arithmetic operators : 2847: ~ (Functions and Variables for itensor) Enter space-separated numbers, `all' or `none': all 15.3 Airy Functions =================== :
なんと12万行もの説明と使用例が記録された。tmuxの履歴でも、ここまでの無茶は出来ない だろう。この技、色々な所で活躍しそう。
$ ghci | tee LOG
これでは、入力が記録されない。かと言って、rlwrapのログだとstderrへのデータは記録 されない。なかなか、難しい。
ああ、maximaのコマンドサーチ ?? も、覚えておくとよい。
(%i5) ?? find 0: bf_find_root (Functions for numerical solution of equations) 1: bf_find_root <1> (Functions for numerical solution of equations) 2: findde (Functions and Variables for ctensor) 3: find_root (Functions for numerical solution of equations) 4: find_root <1> (Functions for numerical solution of equations) 5: find_root_abs (Functions for numerical solution of equations) 6: find_root_error (Functions for numerical solution of equations) 7: find_root_rel (Functions for numerical solution of equations) Enter space-separated numbers, `all' or `none':