全てをchatGPTだけでプログラムしようとした。 プログラム言語は「LUA」というスクリプト言語で、C言語に近い。ところが、私は今までLUAを使ったことが無かった。 そこで、chatGPTと相談しながら作業を進めることにしたのである。 やりたいことは、動画配信で日中は富士山、夜間は水槽の動画を配信すること。
まず、日没と日の入りを求める関数を作るため以下のように指令した。 「動画配信ソフトのLUAを使用して日の出と日の入りを求めるget_SunrizeSunset関数を作成せよ。ただし、引数に緯度経度と求める日を使うこと」 早速プログラムコードが出てきたので、次の指令をした。 「先の関数を使用して日中の場合はTrue、夜間の場合はFalseを返すこと。」 だんだんプログラムが長くなった。 「動画配信ソフトOBSを使用して日中ならFUJI、夜間ならAQUAのシーンを選択すること」 「日の出と日没時間にマージンを持たせるように改良せよ」 幾つか齟齬があって修正を繰り返し一行もソースコードを書かずにプログラムが完成し、動画配信OBSに実装した。
ところが、ここから長かった。 実装すると日没と日の入り時間になってもシーン(カメラ)が切り替わらない。 どうやら日没と日の入り時間が間違っているようだ。 一行もコードを書かないと決めていたので言葉だけで修正を求める。 例えば、「日本時間に対応しているか?」とか「どこかに誤りはないか?」とか。 その都度、黙々と文句を言わずコードを修正して返してくるchatGPT。 途中で「天体の運行がどう」とか「LUAは数学演算が苦手」だとか「さらに精密な計算をしてみる」とか言い訳が始まってプログラムリストはどんどん長くなる。 そこで「おおまかな時間が分かればよい」と指令すると「私には分からないので他の言語のライブラリの使用を勧められた」 この間約半日ほど経過していた。私はただchatGPTのコードをコピペして結果を報告するだけだった。途中面白いのは「以下の値がどうなっているか教えて」とか必死にデバッグに励んでいたことだった。 そして、とうとうchatGPTでは正解にたどり着けなかった。 仕方が無いのでgoogleで検索すると日の入り日没を求める関数がすぐに見つかった。 私にとって初見のLUAだったが何度も修正リストを見ていたので言語の記述方法は理解できたこともあり、見つけた関数の部分だけchatGPTのプログラムと置き換えたらちゃんと動作した。 結果的にだがchatGPTは太陽系の運行から日の出日没を求めようとして失敗したが、googleで見つけた関数は緯度経度を考慮した地球から太陽の位置を求めていた。 私的には精密な日の出日没が欲しかったわけではなく「カメラの切り替えをしたいだけなのでだいたいな時間」が分かればよかったわけだ。 しかし、時間を求めること以外のプログラムはchatGPTのままで動作した。例えば動画配信ソフトでのカメラの切り替えとか日中とかの判断する部分。 つまり、単純に欲しい関数の使用を伝えそれらを組み合わせて全体を構築する部分の運用は意図通りの関数を作成してくれた。 もちろん、目的を達成するために関数という部品をどのように分解して伝えるのかという部分は人間が考えるのだが、その辺も理解して仕様通りの関数を作成してくれた。 この全体のシステムをどのように分解していくのが後工程を楽にするかはシステム設計の基礎が無ければならない。 chatGPTへの指令次第では長大なプログラムリストになり、ミスや修正が難しくなる。 ようするに今回は「日の出日没」の時間を得る関数の入れ替えで簡単に修正できた。 私の反省点として関数を作成する都度、実行結果の予想と結果を報告すれば良かったと思う。 関数の指令を与えながら次第に全体が出来上がるまでコピペのみですませようと少し過信しすぎた。それほどこちらに考える間を与えずプログラムリストを吐き出してくるのにはまってしまった。 というわけで出来上がった動画配信の様子は現在、 https://www.youtube.com/watch?v=mWm6luQ1d7M で見ることができる。 日の出30分前から富士山画像へ、日没後20分後から水槽カメラへと切り替わる。 以降、LUAで動画配信OBSでカメラシーンを切り替えるスクリプトのプログラムリスト。
obs = require('obslua') os = require('os') scene_now = "" scene_WEB251 = "WEB251" -- 富士山カメラ scene_WEB252 = "WEB252" -- 水槽カメラ latitude = 35.68039639541995 -- 緯度経度は東京駅にしてある longitude = 139.76788440520536 sunrise_margin = -30 -- 分単位で指定(2時間前=-120) sunset_margin = 30 -- 分単位で指定(2時間後=120) -- sunrise / sunset calculation function rscalc(latitude, longitude, when) local pi = math.pi local doublepi = pi * 2 local rads = pi / 180.0 local TZ = function(when) local ts = os.time(when) local utcdate, localdate = os.date('!*t', ts), os.date('*t', ts) localdate.isdst = false local diff = os.time(localdate) - os.time(utcdate) return math.floor(diff / 3600) end local range = function(x) local a = x / doublepi local b = doublepi * (a - math.floor(a)) return b < 0 and (doublepi + b) or b end when = when or os.date('*t') local y2k = { year = 2000, month = 1, day = 1 } local y2kdays = os.time(when) - os.time(y2k) y2kdays = math.ceil(y2kdays / 86400) local meanlongitude = range(280.461 * rads + 0.9856474 * rads * y2kdays) local meananomaly = range(357.528 * rads + 0.9856003 * rads * y2kdays) local lambda = range(meanlongitude + 1.915 * rads * math.sin(meananomaly) + rads / 50 * math.sin(2 * meananomaly)) local obliq = 23.439 * rads - y2kdays * rads / 2500000 local alpha = math.atan2(math.cos(obliq) * math.sin(lambda), math.cos(lambda)) local declination = math.asin(math.sin(obliq) * math.sin(lambda)) local LL = meanlongitude - alpha if meanlongitude < pi then LL = LL + doublepi end local dfo = pi / 216.45 if latitude < 0 then dfo = -dfo end local fo = math.min(math.tan(declination + dfo) * math.tan(latitude * rads), 1) local ha = 12 * math.asin(fo) / pi + 6 local timezone = TZ(when) local equation = 12 + timezone + 24 * (1 - LL / doublepi) - longitude / 15 local sunrise, sunset = equation - ha, equation + ha if sunrise > 24 then sunrise = sunrise - 24 end if sunset > 24 then sunset = sunset - 24 end return math.floor(sunrise * 60), math.ceil(sunset * 60) end --本日の日中かどうか審議する function is_daytime(latitude, longitude, sunrise_margin, sunset_margin) local date = os.date("*t") local sunrise, sunset = rscalc(latitude, longitude, date) -- obs.script_log(obs.LOG_INFO, "Sunrize(min): " .. sunrise) -- obs.script_log(obs.LOG_INFO, "Sunset(min): " .. sunset) sunrise = sunrise + sunrise_margin sunset = sunset + sunset_margin local zero_oclock = os.time({year = date.year, month = date.month, day = date.day, hour = 0}) -- 与えられた日の日の出と日の入りの時間(秒)を計算 local sunrise_sec = zero_oclock + sunrise * 60 local sunset_sec = zero_oclock + sunset * 60 local now_sec = os.time(date) --[[ Debug Section START local t = os.date("*t", sunrise_sec) local time_str = string.format("%04d-%02d-%02d %02d:%02d:%02d", t.year, t.month, t.day, t.hour, t.min, t.sec) obs.script_log(obs.LOG_INFO, "Current time: " .. time_str) local t = os.date("*t", sunset_sec) local time_str = string.format("%04d-%02d-%02d %02d:%02d:%02d", t.year, t.month, t.day, t.hour, t.min, t.sec) obs.script_log(obs.LOG_INFO, "Current time: " .. time_str) ]] if sunrise_sec <= now_sec and now_sec <= sunset_sec then return true else return false end end --シーンの切り替え function switch_scene(scene_name) local scenes = obs.obs_frontend_get_scenes() for _, scene in ipairs(scenes) do local scenes_list = obs.obs_source_get_name(scene) if scenes_list == scene_name then if scenes_now ~= scene_name then scenes_now = scene_name obs.obs_frontend_set_current_scene(scene) local t = os.date("*t") local chg_str = string.format("%02d-%02d %02d:%02d -- %s", t.month, t.day, t.hour, t.min, scene_name) obs.script_log(obs.LOG_INFO, "Switched scene: " .. chg_str) end break end end end --日中ならWEB251、夜ならWEB252 function check_time() if is_daytime(latitude, longitude, sunrise_margin, sunset_margin) then switch_scene(scene_WEB251) else switch_scene(scene_WEB252) end end -- function script_description() return "Script to switch scenes at specified times." end -- function script_load(settings) obs.timer_add(check_time, 60 * 1000) end
#chatGPT #プログラム #OBS #動画配信
VIDEO
ChatGPTを「何でも思考し、答えを出すAI」と誤解している人もいますが、これは正確ではありません。ChatGPTは検索エンジンではなく、それゆえに情報を効率的に探し出し、精確に提供する能力を期待すると、その期待は裏切られます。 ChatGPTの本質は大量のテキストデータから言語パターンを学習し、その学習を基に言語を生成することです。それはつまり、質問やコメントに対して確率的に最も適した回答を生成するということです。 しかし、現行のChatGPT-4の言語理解力は非常に高く、特定の領域での質問に対する答えとしては、優れたパートナーとなります。このAIの知識の深さと範囲は、一般的な人間が持つ知識を遥かに超越しています。それは事実です。
以下はPythonプログラムを構築するシンプルな例ですが、これはシステムに精通している人がAIに命令するときに、問題解決に迅速に進むことができる事例と言えます。この場合、目指しているのは、サーバーに記録されたネットワークカメラのIPアドレスログから、カメラ番号に対応するIPアドレスを返すサブプログラムを作ることです。 このタスクは非常に専門的なものであり、ChatGPTが使用者の意図を理解している点に注目すべきです。また、質問の内容は実際にそのまま入力されていることも重要です。これらは事実です。 質問: 以下のような文字列がある。この中からlivecam30の行にあるIP4のアドレスを抽出するpythonのソースを書け livecam23 ftp ***.249.22.197 livecam30 vsftpd:22468 ***.16.152.214 Mon Jun 5 12:40 - 12:40 (00:00) wtmp begins Thu Jun 1 04:27:10 2023 livecam20 vsftpd:22462 ***.125.253.216 Mon Jun 5 12:40 - 12:40 (00:00) wtmp begins Thu Jun 1 04:27:10 2023 livecam11 vsftpd:21738 ***.22.218.36 Mon Jun 5 12:30 - 12:30 (00:00) wtmp begins Thu Jun 1 04:27:10 2023 livecam22 vsftpd:21733 ***.157.4.56 Mon Jun 5 12:30 - 12:30 (00:00) 回答: 以下は、与えられた文字列から"livecam30"の行にあるIPv4アドレスを抽出するPythonのソースコードです。
(解説) まずは小手調べ。AIが最初の質問にどこまで適切に回答できるか様子を見た。その結果、意図通りの回答を得た。 IP4の理解と当方が意図する文字列抽出を完全に理解している。 質問: 上記の文字列はサーバー http://abc.com/log.dat から得られる。ソースを書き換えよ。 回答: 了解です。指定されたURL(http://abc.com/log.dat )からデータを取得し、そのデータから"livecam30"の行にあるIPv4アドレスを抽出するPythonのソースコードを以下に示します。
(解説) このように、徐々に問題をステップアップするほうがAIとの無駄なやり取りを減らす。 質問: extract_ipv4_addressはget_ip_addressに、引数はターゲットURLと文字列livecam30に変更。 回答: 了解しました。extract_ipv4_address関数をget_ip_addressにリネームし、引数をターゲットURLと文字列"livecam30"に変更したソースコードを以下に示します。
(解説) ここで行いたい事はモジュールを汎用的にし、どの「livecam番号」でも使用できるように変更すること。 当方の欲しい汎用的なプログラム仕様に変更したのだがchatGPTは完全に正解を出している。 質問: pattern = r"{0}.*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})".format(target_string) 行でエラーになります 回答: 申し訳ありません、誤りがありました。正しいソースコードを以下に示します。
(解説) 実際に得られたプログラムを実行したがエラーとなったのでエラー箇所を指摘し再度質問した。 質問: 正規表現の文字列{}がおかしいのでは? 回答: 申し訳ありません、おっしゃる通りです。正規表現の文字列に使用される波括弧 {} は、Pythonの文字列フォーマットにも使用される特殊文字です。そのため、波括弧を正規表現パターン内で使用する場合には、エスケープが必要です。おっしゃる通りに修正し、正しいソースコードを以下に示します。
(解説) 再び得られたプログラムを実行したがまた同じ個所でエラーとなったので当方にて怪しい部分を指摘してみた。 その結果、目的のプログラムを得たので以下にすべてのソースを掲載する。 import re import urllib.request def get_ip_address(url, target_string): response = urllib.request.urlopen(url) data = response.read().decode("utf-8") pattern = r"{}.*?(\d{{1,3}}\.\d{{1,3}}\.\d{{1,3}}\.\d{{1,3}})".format(re.escape(target_string)) match = re.search(pattern, data) if match: return match.group(1) else: return None # ターゲットURLと文字列の設定 url = "http://abc.com/log.dat" target_string = "livecam30" # IPv4アドレスの抽出 ipv4_address = get_ip_address(url, target_string) print(ipv4_address) 実行結果は「***.16.152.214」とIP4のアドレスを別サーバーに保管されているログデータから抽出できた。
総括 通常、人間に仕事を頼む際には、モジュールの仕様書を提出してからプログラミングを依頼しますが、ChatGPTに仕事を依頼すると、その手間が大幅に削減されます。初めての質問を人間に頼んだ場合、そのタスクを完了できる技術者はどれくらいいただろうか?また、頼んだ人間がある程度の知識を持っていたとしても、どれくらいの時間で完成させただろうか? このタスクを完了するのにChatGPTは30分もかかりません。人間に依頼すると、各種の知識を前提に打ち合わせを行い、モジュールの仕様書を作成するまでを考えると、作業完了までにはかなりの時間を必要とします。特に、人間が必要な知識を持っていなければ、時間は日単位で経過するでしょう。 現在のChatGPTは、特定の領域の文章ベースの作業において驚異的な能力を発揮します。今後は、手足やセンサーを持った状態でも、一定の労働を可能にするでしょう。これが現実です。 現代のプログラミング言語は、システムを構築する前に、どのモジュールが存在するかを事前に調査する必要があります。この過程が非常に手間となるのです。しかし、AIは大量の既存の知識を探索し、利用可能かどうかを判断し、それを技術者に提供する能力を持っています。これは確かな事実です。 多くの人がChatGPTに些細な質問を投げかけ、それが真実か否かを議論していますが、その使用方法は間違っていると言えます。正しい使用方法は、人間の知識を基に、ChatGPTに対して適切な質問と回答を用いて、面倒な作業部分をどの程度補完できるかを確認しながら作業を進めることです。これは確かな事実であり、その結果もそれを証明しています。 ちなみに今までの文章はchatGPTに「私の書きなぐりの文章を断定調で読みやすい文章に編集せよ」と指令をして書かせた文章。 以下に最後の章のみ元となった文章の原文を記しておく。 以上の事を人間に頼むときにはモジュール仕様書を渡してからプログラムしてもらうのだが、chatGPTに仕事を頼むとその手間が大いに省ける。 この例において、もし一番最初の質問を人間に行った場合にはいったいどれだけの技術者がこのモジュールを仕上げてくれただろうか?頼んだ人間に多少知識があってもどのくらいの時間で仕上げてくれただろうか? これを仕上げるのに要した時間は30分もない。同じことを人間に頼むと諸々の知識を前提に打ち合わせを行ってからモジュール仕様書作成までを考えると作業終了まで膨大な時間を要する。特に人間に諸々の知識が無ければ日にち単位で時間が過ぎてゆく。 現在のchatGPTは特定分野の文章ベースの作業においてとんでもない力量を示すが、将来は手足とセンサーが付いたとしたらある程度の労働は可能になるだろう。翻ってコンピュータ技術者なら知識の乏しい人に対して今回の設問を実施した場合の難しさを理解していると思う。それが今回の例では短く抽象的な命令を的確にくみ取り、すべて間違いなくミッションをこなしてしまった。 現在のプログラム言語はどのようなモジュールがあるか事前に調べてからシステム構築する仕様になっている。これが実に面倒くさいのだ。昔なら「面倒くさいから自分で作ってしまえ」ということを良く行ったし許容されていた。しかし現在のシステムは膨大な過去の遺産を調べてから使用可能かどうか判断する作業から始める。すぐに結果の欲しいシステム開発の場合には実に面倒な作業だ。上記の例では「しれっと」reやurllib.requestのモジュールをchatGPTは使用しているが、初めて経験する仕様のプログラムではこうはいかない。つまり、AIが膨大な過去の遺産を調べて生かしてくれるだけで技術者にとっては大いに参考になるのだ。 いかがだろうか? 世間ではchatGPTにくだらない質問をして正解だとかウソを言っているとか言っているが、その使い方が誤っているとしか思えない。 正しい使い方は、人間の知識をベースにchatGPTに対して適切な質問と回答で面倒な作業部分を如何に補ってくれるであろうかを確認しながら作業を進めていくという事だと思う。 chatGPTに校正を頼んだ結果、私の個性が死んでいますね…… #chatGPT #AI #人工知能 #プログラム #コンピュータ
山梨ではシン仮面ライダーの公開が終わった。そこで、見た感想を書いてみる。 一言でいうと「たいへん良かったし、面白かった」に尽きる。特に50代以降の人には刺さるものがあったと思う。 個人的に最初の仮面ライダーを見たのは小学生2年のころか?印象は暗く怖いイメージがあった。今思えばショッカーの行動原理は当時の学生運動の陰湿さの敗北と重なる。 ちょうどこのころ、あさま山荘事件 をきっかけに山岳ベース事件 が明るみになったころで(特に漫画版の)ショッカーには当時の学生運動と同じ香りがしていた。新仮面ライダーにはまさにその香りが残っており、ノスタルジーを感じた次第である。
また随所にコアな石ノ森章太郎 と初代仮面ライダー へのリスペクトが入っており、監督の愛も感じた。裏返せば平成以降の仮面ライダーファンや事情を良く知らない人には作品の賛否が分かれるだろうと思った。 しかし、そんなことはどうでも良く新仮面ライダーは個人的に良かったと言える。
ここで少し作品の内容に触れるが、序盤の蜘蛛オーグ(旧クモ男)を倒すまではYoutubeで公開されているようで、ライダーの制御できない圧倒的な力と暴力を原作の設定通りに表現していた。思い起こせば初代仮面ライダーの時にあったコウモリ男との戦いでの血しぶきシーンの再現かと思われるが、当時の解説本の設定通りに行うとこうだろうなと感じた。 そういえば、新仮面ライダーと蝙蝠オーグとの戦いのアジトは何と「河口湖ステラシアター 」だった。初代仮面ライダー1話目の序盤に出てくる本郷猛と立花藤兵衛がバイクの練習をしているところへショッカーたちが襲ってくるシーンは河口湖ステラシアター近くだったことを思い出した。ここでのバイクに乗りながら風を受けて変身するシーンは理屈抜きにカッコイイ。 蜂オーグとの戦いのCGは石ノ森漫画お得意の高速戦闘シーンのオマージュだろう。あの印象的な加速装置 の描写を石ノ森がいろいろ工夫して描いた1コマを映像にするとああなるんだなと見ていて思ったし、ショッカーライダーとの暗いトンネルでの戦闘はテレビシリーズで同じシーンを見た記憶がある。そもそも最初のライダーの画面は先に記した通り雰囲気も暗いが映像も常に暗かった。映画の雰囲気も昔懐かしいブラウン管テレビの70年代の雰囲気バッチリだった。
庵野監督 は人形に魂の宿る設定が好きだなと感じた。これは特に日本人なら神道の考えに共感できると思う。万物の魂の集合としての炎=魂 が存在し、炎の一部が分離し物に宿る。役目を終えた魂は再び物を離れ一つの魂へと集合して行く。繰り返すが日本人にしか分からない宗教観だ。靖国神社の戦没者を分祀できない理由と一緒で一度炎に集合した個々の炎はもはやかつての形に分離できない。 以上の事を映画マトリクスのようなVRと混同視される(その説明のほうが分かりやすい)が本質的に違うことは一言添えておく。 今回の新仮面ライダーはプラーナ というインド哲学に寄ったが庵野監督の本質は神道の魂の融合だろう。ウルトラマン にしてもゴジラ にしてもエヴァンゲリオン にしても、そのものの中に魂が宿ったり離れたりする様はすべてに共通している。これはおそらく、庵野監督が拠り所にしているオタク作品群の数々に正当性を与えるため、長年に渡り頭の中で生み出した必殺技に他ならない。簡単に言うと、庵野監督は自分の好きな作品世界を本気で信じており、それらに正当性を与える行為をずっと模索し続けてきた結果生み出した方法論があるということだ。
話を新仮面ライダーに戻すと、蝶オーグの言っていたハビタット世界は魂の帰ってゆく集合体の世界の事だがエヴァの世界観と一致する。しかしエヴァでは肯定的にその世界に行きたいと思っていたものが新仮面ライダー(新エヴァでも)では否定的な事が面白い。庵野監督の心の変化を感じられる。誰でも愛する者が帰っていった一つの魂の場所に触れたいと思う時があるが、現実に生きることに気が付くとそればかりに囚われていてはいけないと気付く。言い換えると、いつまでも空想の世界に逃げていてはいけないことを庵野監督は大人になって気が付いたのだろうか? 新仮面ライダーの物語終盤ははからずも原作に近い形で1号ライダーと2号ライダーが融合し新ライダーとなって角島 へと走ってゆく場面で終わる。新エヴァも新仮面ライダーも庵野監督の出身地である山口県の風景の中に走り去ってゆく。つまり、庵野監督の私小説とノスタルジーとオタク気質、そして昭和の小難しい日本映画に触れることができた人は感動できる作品だったなと感じた次第です。
フィギュアたちは所有物を撮影、ステラシアターはまだ屋根の無い時の画像、角島大橋 は2011年5月25日撮影。
#模型 #フィギュア #映画
明日は富士山五合目ヒルクライムだそうで、昨日の大雨に続きスバルラインは通行止めに。その少し前、五合目のライブカメラの復旧に行った来た。https://live.fujigoko.tv/?n=21&b=0 月曜にならなければ大雨の影響でカメラが無事かどうか判明できない。 それはそうと帰り道の四合目でランボルギニーミウラとフェラーリに遭遇し写真を撮らせてもらった。2台合わせて3億5千万円だそうだ。ミウラが2億円だそうで。 その後昼には河口湖のオムライス有名店リロンディルに行き、溢れる湯で今ちょっと話題の玉川温泉からのうな重でおなじみ初花温泉と温泉のはしごをした盛りだくさんの一日でした。
ミウラ2億円とフェラーリ1億5千万円の図。 まさに子供のころのスーパーカーだった。
リロンデルは燕の意味だとか。
湯船から洗い場にあふれる湯で有名になった玉川温泉。単に洗い場の床が凹しているだかかも?
ライブカメラを付けた日はうな重で打ち上げ。
#ライブカメラ #温泉