タグ「Python」を含む投稿[119件](7ページ目)
オレメモです。
PythonからC言語の関数を呼び出す(基本編)
タイトルの通りです。
部分の説明で満足しちゃって全体が見えない解説がネットにも書籍にも多い中、この作者は部分の説明から入って全体を見せてくれるのでわかりやすい。
C言語とPythonの両方を知らないと意味不明の暗号でしかありませんが・・・
#Python
PythonからC言語の関数を呼び出す(基本編)
タイトルの通りです。
部分の説明で満足しちゃって全体が見えない解説がネットにも書籍にも多い中、この作者は部分の説明から入って全体を見せてくれるのでわかりやすい。
C言語とPythonの両方を知らないと意味不明の暗号でしかありませんが・・・
#Python
このところライトアップのご要望を多く頂きます。
特定の日時に人集めることが難しいため、特に行政さんではイベント予算の消化のためにライトアップをお考えになる事例が多いようです。
ただ、長くて2か月の半仮設に適したライトアップの制御システムは既製品にありません。電源は電気工事さんにタイマーとリレーを施工してもらえば何とでもなりますが、DMXを出力する制御盤はありそうで無いのです。5時間のライトアップをDMXレコーダーで現尺保存などしたくありませんし。
ならば作ってしまえとなるワケです。時刻をトリガーにシーンをめくる簡素なDMXコンソールってイメージですが、どうせならIoT的な手法でインターネット経由の遠隔操作が出来たらいいんじゃないかと。制御の核にRaspberryPiなどのLinuxベースのマイコンを用い、ポケットwi-fiを介してVPN接続するのです。VPNによってローカルLANと等しい接続をしてしまえばJAVA-scriptとPythonのsocketで自由度の高い制御が出来ます。現地の装置との接続を仲介するサーバーが別途必要なので、インフラ整備に物と手間と維持費がかかりますし、インターネットサーバーを扱うスキルも必要です。ナンのことすか?って話ですけどね。
未解決の課題は少なくありませんが、インターネットを介したVPNで遠隔操作する手段はとうの昔に獲得済みですから、ブラウザで操作できるコンソールをRaspberryPi上に構成すれば必要な要素は揃います。IoT照明コンソール(笑
未解決の主な課題はC言語によるPython用の計算ライブラリを書くことです。調光データの計算(マスター値を当てるとか、複数のシーンのレベルをマージするとか)に特化したものですが、繰り返し処理が激遅なPythonを補完するだけですので、PtyhonライブラリをC言語で書く教科書を熟読すればいけると思います。もちろんnumpyでも出来ることですが、繰り返し処理を軽くするには専用ライブラリがいいかなと。特化しといた方が書きやすいし。この案件に限らず、いずれ獲得したいライブラリです。
本題のような余談ですが、PythonはC言語より100倍楽に書けるけど100倍遅いイメージです。Pythonは変数の型に自由度があること(整数の除算の結果が自動的に浮動小数点なるとか)が書きやすい特徴の一つですが、Pythonのコアが変数の「型」を推測するのに時間がかかるのだそうです。代表的な例がfor文を多用した際の激遅っぷりです。for文は繰り返しのステップ毎に扱う変数の型を推測しますから遅くなるのは当然です。C言語は変数の型が厳密に扱われて気難しい反面、優しさ全開のアシスト機能が無いので速いのです。あちらを立てればこちらが立たず。処理内容に寄ると言ってしまえばそれまでですが、単精度で単純な計算を延々と続ける調光卓みたいなシステムでは繰り返しが多い計算をC言語によるライブラリとして書くメリットは多大なのです。どうやら、Pythonというシステムはそんな使い方をするようにデザインされているとのこと。PythonはC言語で書かれたガチなライブラリを出来るだけ楽に使うための踏み台だとイメージすると良いようです。
懸念されることは、世の中がコロナ前の状況に戻ってしまうと、ライトアップの件数も元に戻ってしまうことです。作っても使わないと意味ありません。
#照明器具 #Python
特定の日時に人集めることが難しいため、特に行政さんではイベント予算の消化のためにライトアップをお考えになる事例が多いようです。
ただ、長くて2か月の半仮設に適したライトアップの制御システムは既製品にありません。電源は電気工事さんにタイマーとリレーを施工してもらえば何とでもなりますが、DMXを出力する制御盤はありそうで無いのです。5時間のライトアップをDMXレコーダーで現尺保存などしたくありませんし。
ならば作ってしまえとなるワケです。時刻をトリガーにシーンをめくる簡素なDMXコンソールってイメージですが、どうせならIoT的な手法でインターネット経由の遠隔操作が出来たらいいんじゃないかと。制御の核にRaspberryPiなどのLinuxベースのマイコンを用い、ポケットwi-fiを介してVPN接続するのです。VPNによってローカルLANと等しい接続をしてしまえばJAVA-scriptとPythonのsocketで自由度の高い制御が出来ます。現地の装置との接続を仲介するサーバーが別途必要なので、インフラ整備に物と手間と維持費がかかりますし、インターネットサーバーを扱うスキルも必要です。ナンのことすか?って話ですけどね。
未解決の課題は少なくありませんが、インターネットを介したVPNで遠隔操作する手段はとうの昔に獲得済みですから、ブラウザで操作できるコンソールをRaspberryPi上に構成すれば必要な要素は揃います。IoT照明コンソール(笑
未解決の主な課題はC言語によるPython用の計算ライブラリを書くことです。調光データの計算(マスター値を当てるとか、複数のシーンのレベルをマージするとか)に特化したものですが、繰り返し処理が激遅なPythonを補完するだけですので、PtyhonライブラリをC言語で書く教科書を熟読すればいけると思います。もちろんnumpyでも出来ることですが、繰り返し処理を軽くするには専用ライブラリがいいかなと。特化しといた方が書きやすいし。この案件に限らず、いずれ獲得したいライブラリです。
本題のような余談ですが、PythonはC言語より100倍楽に書けるけど100倍遅いイメージです。Pythonは変数の型に自由度があること(整数の除算の結果が自動的に浮動小数点なるとか)が書きやすい特徴の一つですが、Pythonのコアが変数の「型」を推測するのに時間がかかるのだそうです。代表的な例がfor文を多用した際の激遅っぷりです。for文は繰り返しのステップ毎に扱う変数の型を推測しますから遅くなるのは当然です。C言語は変数の型が厳密に扱われて気難しい反面、優しさ全開のアシスト機能が無いので速いのです。あちらを立てればこちらが立たず。処理内容に寄ると言ってしまえばそれまでですが、単精度で単純な計算を延々と続ける調光卓みたいなシステムでは繰り返しが多い計算をC言語によるライブラリとして書くメリットは多大なのです。どうやら、Pythonというシステムはそんな使い方をするようにデザインされているとのこと。PythonはC言語で書かれたガチなライブラリを出来るだけ楽に使うための踏み台だとイメージすると良いようです。
懸念されることは、世の中がコロナ前の状況に戻ってしまうと、ライトアップの件数も元に戻ってしまうことです。作っても使わないと意味ありません。
#照明器具 #Python
シリアル化の手順は次の通りです。
オレメモです。
1) ライブラリをインポートします。
>>> import numpy as np
>>> import pickle
2) テスト用のnumpy.arrayを作ります。とりあえずはすべてゼロのuint8です。
>>> z = np.zeros(( 192, 8, 512 ), dtype=np.uint8 )
※ dtypeで変数の型を指定します。指定しないとOSのbit長のintになります。
※ 値の計算をするならuint16以上の型にしなければなりませんが、今のところArt-Netエンジン内では置き換えと比較しかしませんのでuint8で運用できそうです。
3) テスト用のtupleを作ります。
>>> y = ( 'tests', z )
※ 'tests'という文字列と(2)で作ったnumpy.arrayのtupleです。
4) シリアル化します。
>>> x = pickle.dumps( y )
これでtuple:yが一列のバイナリとなり、scoketで通信できる状態になります。
5) 復号します。
>>> w = pickle.loads( x )
※ wはyと同じtupleです。正しく復号されました。
numpy自体にもシリアル化/復号の方法があるようですが、型の違うデータを一括でやり取りしたいのでtupleをpickleで扱います。
この処理の速度が十分かどうかはこれからの確認です。
#Python
オレメモです。
1) ライブラリをインポートします。
>>> import numpy as np
>>> import pickle
2) テスト用のnumpy.arrayを作ります。とりあえずはすべてゼロのuint8です。
>>> z = np.zeros(( 192, 8, 512 ), dtype=np.uint8 )
※ dtypeで変数の型を指定します。指定しないとOSのbit長のintになります。
※ 値の計算をするならuint16以上の型にしなければなりませんが、今のところArt-Netエンジン内では置き換えと比較しかしませんのでuint8で運用できそうです。
3) テスト用のtupleを作ります。
>>> y = ( 'tests', z )
※ 'tests'という文字列と(2)で作ったnumpy.arrayのtupleです。
4) シリアル化します。
>>> x = pickle.dumps( y )
これでtuple:yが一列のバイナリとなり、scoketで通信できる状態になります。
5) 復号します。
>>> w = pickle.loads( x )
※ wはyと同じtupleです。正しく復号されました。
numpy自体にもシリアル化/復号の方法があるようですが、型の違うデータを一括でやり取りしたいのでtupleをpickleで扱います。
この処理の速度が十分かどうかはこれからの確認です。
#Python
numpy.arrayを含むtupleをsocketで送るにはシリアル化ってのをすればいいらしい。pythonのオブジェクトをバイナリ化する方法とのこと。
pickleというライブラリを使います。pickle.dumps()でシリアル化し、pickle.loads()で戻します。
テキストと3次元のnumpy.arrayが混在するtupleが一発で処理出来ました。
変換したデータのtypeはbytesですからsocketで送れるハズです。
ただ、pickleのシリアル化/復号には時間がかかる様子。
先人の調査によると、scoket自体はとても速いけれどpickleの処理が案外遅くて総処理時間は他の方法と似たり寄ったりみたい。
ただ、先人の比較方法はデータ量を起点にする比較が主で、都度のデータは少なくコネクションの回数が多いケースの比較ではありません。multiprocessingのQueueはコネクション毎のマネージ処理が重い感じがするので、コネクション自体は軽いsocketに分があるかもしれません。
また、DMXのスロットデータを格納するnumpy.arrayは何も指定しないとint32やint64になりますが、uint8やuint16を指定すれば1スロット当たりのデータ長は小さくなります。つまり、データ総量が小さくなります。
試さないとわからんですけど、オーバーヘッドが大きい通信処理でデータ量を減らせば十分な速度を確保できる期待感があります。DMXの1スロットは1バイトですから、Art-Netエンジンではスロットに対する計算処理をせずにuint8で運用するのがいいのかもしれません。今のところ、比較抽出のnumpy.maxはあってもスロットデータに計算らしい計算は当てないのでuint8で運用しても問題無さそう。
つか、通信自体はsocketが凄く軽いことに驚いた。PythonというよりOS本体に依存するので当然かもしれませんが。
#Python
pickleというライブラリを使います。pickle.dumps()でシリアル化し、pickle.loads()で戻します。
テキストと3次元のnumpy.arrayが混在するtupleが一発で処理出来ました。
変換したデータのtypeはbytesですからsocketで送れるハズです。
ただ、pickleのシリアル化/復号には時間がかかる様子。
先人の調査によると、scoket自体はとても速いけれどpickleの処理が案外遅くて総処理時間は他の方法と似たり寄ったりみたい。
ただ、先人の比較方法はデータ量を起点にする比較が主で、都度のデータは少なくコネクションの回数が多いケースの比較ではありません。multiprocessingのQueueはコネクション毎のマネージ処理が重い感じがするので、コネクション自体は軽いsocketに分があるかもしれません。
また、DMXのスロットデータを格納するnumpy.arrayは何も指定しないとint32やint64になりますが、uint8やuint16を指定すれば1スロット当たりのデータ長は小さくなります。つまり、データ総量が小さくなります。
試さないとわからんですけど、オーバーヘッドが大きい通信処理でデータ量を減らせば十分な速度を確保できる期待感があります。DMXの1スロットは1バイトですから、Art-Netエンジンではスロットに対する計算処理をせずにuint8で運用するのがいいのかもしれません。今のところ、比較抽出のnumpy.maxはあってもスロットデータに計算らしい計算は当てないのでuint8で運用しても問題無さそう。
つか、通信自体はsocketが凄く軽いことに驚いた。PythonというよりOS本体に依存するので当然かもしれませんが。
#Python
Art-Netエンジンの構成を整理していますが、そういやプロセス間通信はどうしましょう。
PythonではmultiprocessingのQueueが予想以上に遅くて使い物になりません。便利なんですけどね。
ネットの情報ではPipeや共有メモリが速いとあります。ですが、socketもQueueより速そうなレポートが多く見受けられます。
実験してみないとわかりませんが、速度が足りるならsocketにした方が将来性があります。なぜなら、内部でのプロセス間通信も別プロセッサとの協調動作も設定するIPアドレスとポートが違うだけで全く同じプログラムで実現可能だからです。Pipeや共有メモリよりもsocketはシンプルで扱いやすいので速度が十分なら尚更です。
Art-NetとEtherNetを共用するのは避けた方が良さそうですが、ローレベルのハードウェアを扱いやすいRaspberryPiと計算能力が高いPCを組合せば得意分野を活かして良い結果を出せるような気がします。もし調光卓を考えるならこの方法は必須かもしれません。もちろん、Art-NetエンジンそのものをPCに実装するのもアリでですけど。
これまではQueueベースで書いてきましたが、タプルをバイナリ化してsocketで通信する方法から試してみましょう。
#Python #[Art-Net]
PythonではmultiprocessingのQueueが予想以上に遅くて使い物になりません。便利なんですけどね。
ネットの情報ではPipeや共有メモリが速いとあります。ですが、socketもQueueより速そうなレポートが多く見受けられます。
実験してみないとわかりませんが、速度が足りるならsocketにした方が将来性があります。なぜなら、内部でのプロセス間通信も別プロセッサとの協調動作も設定するIPアドレスとポートが違うだけで全く同じプログラムで実現可能だからです。Pipeや共有メモリよりもsocketはシンプルで扱いやすいので速度が十分なら尚更です。
Art-NetとEtherNetを共用するのは避けた方が良さそうですが、ローレベルのハードウェアを扱いやすいRaspberryPiと計算能力が高いPCを組合せば得意分野を活かして良い結果を出せるような気がします。もし調光卓を考えるならこの方法は必須かもしれません。もちろん、Art-NetエンジンそのものをPCに実装するのもアリでですけど。
これまではQueueベースで書いてきましたが、タプルをバイナリ化してsocketで通信する方法から試してみましょう。
#Python #[Art-Net]
実作業はなかなか進みませんが、Art-Netドライバの方針が整理出来ています。
Pythonについて継続して調べていますが、そんな中で遭遇した「PythonはC++で書かれたライブラリを呼び出すプラットホーム」というご意見に納得。
Pythonは処理が遅い。変数の型の定義が曖昧でも何となく動くのは便利だけど、大事な時に変数の型のミスマッチでエラーが出るのは面倒。けれど処理の構図を作る生産性は高く、変数の型も意識して書けば問題になりません。C++で部分の関数を書いてPythonでまとめるのは良い方法だと思うのです。
なので、先のご意見には納得なのです。
Cythonではなく、Pythonコードから完全なバイナリに直接コンパイルする方法があったらなと思います。
#Python
Pythonについて継続して調べていますが、そんな中で遭遇した「PythonはC++で書かれたライブラリを呼び出すプラットホーム」というご意見に納得。
Pythonは処理が遅い。変数の型の定義が曖昧でも何となく動くのは便利だけど、大事な時に変数の型のミスマッチでエラーが出るのは面倒。けれど処理の構図を作る生産性は高く、変数の型も意識して書けば問題になりません。C++で部分の関数を書いてPythonでまとめるのは良い方法だと思うのです。
なので、先のご意見には納得なのです。
Cythonではなく、Pythonコードから完全なバイナリに直接コンパイルする方法があったらなと思います。
#Python
Art-Netドライバには追加しないといけないことがあります。
受信したデータにパッチなどを施して送信することには成功しているのですが、現時点ではフリーフェーダーやスタックフェーダーを考慮していません。
当初は[受信するプロセス]-[受信部からデータを取り出して加工するプロセス]-[加工したデータを受け取って送信するプロセス]と分けてイメージしていたので加工するプロセスで出来るだろうと思っていたのですが、プロセス間通信のオーバーヘッドを軽減するためにこれらを1つのプロセスにしましたので同じ考え方はできません。
今もパッチ等のマップデータはプロセス間通信で差し込んでいますが、マップデータが変更された時だけ実行すればいいので頻度が低く問題になりません。されど、即反応して欲しいフェーダー操作の情報は違ってきます。データをどう扱うか、どの位置で処理するか、ちょっと難しくなってきます。
フリーフェーダーだけなら特別なIPアドレス(例えば127.0.0.1)を用いた特別な経路でデータを取り込んでArt-Netと同列に処理する方法もありますが、スタックフェーダーにするにはちょっと無理があるように思ったりします。
ただ、これらのフェーダーはバックアップ的な意味合いが強いので反応がやや遅くてもいいかもしれません。これが許されるならプロセス間通信でデータを差し込んでもいいでしょう。
次のステップに入る前にここは片付けておかないといけません。
追記
スタックフェーダーの方法はアイデアが出ました。Art-Netの入力を記憶します。ただし、記憶するユニバースなりスロットを指定出来ないとディマー以外の動作を邪魔することがあるので一種のフィルターが必要です。フィルターがあればフリーフェーダー的にも機能します。排他的ではなくHTPミックスになりますが、この方がいいでしょう。
操作としては、記憶したい状態でスタックフェーダーとユニバースやスロットを指定してストアします。ユニバースやスロットが無指定ならすべてを記憶です。
#Python #[Art-Net]
受信したデータにパッチなどを施して送信することには成功しているのですが、現時点ではフリーフェーダーやスタックフェーダーを考慮していません。
当初は[受信するプロセス]-[受信部からデータを取り出して加工するプロセス]-[加工したデータを受け取って送信するプロセス]と分けてイメージしていたので加工するプロセスで出来るだろうと思っていたのですが、プロセス間通信のオーバーヘッドを軽減するためにこれらを1つのプロセスにしましたので同じ考え方はできません。
今もパッチ等のマップデータはプロセス間通信で差し込んでいますが、マップデータが変更された時だけ実行すればいいので頻度が低く問題になりません。されど、即反応して欲しいフェーダー操作の情報は違ってきます。データをどう扱うか、どの位置で処理するか、ちょっと難しくなってきます。
フリーフェーダーだけなら特別なIPアドレス(例えば127.0.0.1)を用いた特別な経路でデータを取り込んでArt-Netと同列に処理する方法もありますが、スタックフェーダーにするにはちょっと無理があるように思ったりします。
ただ、これらのフェーダーはバックアップ的な意味合いが強いので反応がやや遅くてもいいかもしれません。これが許されるならプロセス間通信でデータを差し込んでもいいでしょう。
次のステップに入る前にここは片付けておかないといけません。
追記
スタックフェーダーの方法はアイデアが出ました。Art-Netの入力を記憶します。ただし、記憶するユニバースなりスロットを指定出来ないとディマー以外の動作を邪魔することがあるので一種のフィルターが必要です。フィルターがあればフリーフェーダー的にも機能します。排他的ではなくHTPミックスになりますが、この方がいいでしょう。
操作としては、記憶したい状態でスタックフェーダーとユニバースやスロットを指定してストアします。ユニバースやスロットが無指定ならすべてを記憶です。
#Python #[Art-Net]
オフですが、用事が早く終わったのでArt-Netを書き書き。
ライブラリ化が完了。importしてインスタンスを作ればArt-Netの受送信が始まり、インスタンスから関数を呼び出して設定変更や現在値の読み出しが出来ます。
とりあえずこんなもんかな。
追記
送信元を切り替える動作も確認しました。
まだユーザーが選択するようにはしていませんが、5秒毎に切り替えるテストプログラムで正常に動作。
SPI-DMXの処理もイメージがまとまってきました。Art-Netの出力処理内にthreadingで間借りすればすんなりいきそうです。
#Python #[Art-Net]
ライブラリ化が完了。importしてインスタンスを作ればArt-Netの受送信が始まり、インスタンスから関数を呼び出して設定変更や現在値の読み出しが出来ます。
とりあえずこんなもんかな。
追記
送信元を切り替える動作も確認しました。
まだユーザーが選択するようにはしていませんが、5秒毎に切り替えるテストプログラムで正常に動作。
SPI-DMXの処理もイメージがまとまってきました。Art-Netの出力処理内にthreadingで間借りすればすんなりいきそうです。
#Python #[Art-Net]
Art-Netパッチは一番の課題をクリアしたワケです。
規格書を翻訳するところから始まって4ヶ月間、ヒマが無くても考え続けてきましたから、嬉しいと言えば嬉しいですが、肩の荷が下りてホッとした気持ちが強いです。
予想外の何かは残っていると思いますが、一番大きな山を越えたのかな。
今後はimport出来るライブラリとしてまとめ上げ、先日基板を作ったSPI-DMXの試作です。
ライブラリにするのはそれほど難しくありません。動作試験用に書いたmainを機能別に関数化して外から呼べるようにするだけです。
SPI-DMXは、Art-Netパッチに組み込むか、別の装置としてArt-Netデコーダにするか、試作しながら考えたいと思います。RaspberryPiのSPIで大きなデータを扱ったことがないので、Art-Netパッチに組み入れられるかわからんのです。
最終的な装置にまとめ上げるには筐体の製作もあります。簡単そうで難しい電源の入り切りや停電対策などもあります。
まだまだやらねばならないことが多く、主機能が一応動いたからと喜んでもいられんのです。
近々の目標は、最低限の設定操作が出来るところまで作ってDMX-Delayをリクエストしてくださったプランナーさんに主機能を確認して頂くことです。望まれているニュアンスで遅れるかが最も大事ですから。
ベニヤ板に基板やモジュールをネジ止めした姿での確認になりそうですが、中身が決まらないと筐体の設計は出来ませんのでよいのです。
願わくば、P社のW君にも確認してもらいたいなぁ~(笑
#Python #[Art-Net]
規格書を翻訳するところから始まって4ヶ月間、ヒマが無くても考え続けてきましたから、嬉しいと言えば嬉しいですが、肩の荷が下りてホッとした気持ちが強いです。
予想外の何かは残っていると思いますが、一番大きな山を越えたのかな。
今後はimport出来るライブラリとしてまとめ上げ、先日基板を作ったSPI-DMXの試作です。
ライブラリにするのはそれほど難しくありません。動作試験用に書いたmainを機能別に関数化して外から呼べるようにするだけです。
SPI-DMXは、Art-Netパッチに組み込むか、別の装置としてArt-Netデコーダにするか、試作しながら考えたいと思います。RaspberryPiのSPIで大きなデータを扱ったことがないので、Art-Netパッチに組み入れられるかわからんのです。
最終的な装置にまとめ上げるには筐体の製作もあります。簡単そうで難しい電源の入り切りや停電対策などもあります。
まだまだやらねばならないことが多く、主機能が一応動いたからと喜んでもいられんのです。
近々の目標は、最低限の設定操作が出来るところまで作ってDMX-Delayをリクエストしてくださったプランナーさんに主機能を確認して頂くことです。望まれているニュアンスで遅れるかが最も大事ですから。
ベニヤ板に基板やモジュールをネジ止めした姿での確認になりそうですが、中身が決まらないと筐体の設計は出来ませんのでよいのです。
願わくば、P社のW君にも確認してもらいたいなぁ~(笑
#Python #[Art-Net]
Art-Netはテスト用のマップでパッチとディレイが機能しました。プロファイルカーブはこれからですが、パッチとディレイが動けば理屈は同じです。
ただ、配列変数の扱いで少し難儀しました。参照渡しになる規則がまだわからん・・・
ドライバレベルの基本動作がようやく出来た段階なので先は長いですが、処理負荷も軽くていいんじゃないかと。
ただ、処理を増やしたのに処理負荷が減っている。動くべきは動いているのに何故?
追記
プロファイルカーブの処理も試し書きが一発OK。
ムービングで試しましたが、ディマーだけノンディマーになる。
もちろん、ディマーにだけディレイをかけられる。
なんか面白い。
どうやら処理の核は出来たらしい。
一晩寝かせてから総チェックします。
#Python #[Art-Net]
ただ、配列変数の扱いで少し難儀しました。参照渡しになる規則がまだわからん・・・
ドライバレベルの基本動作がようやく出来た段階なので先は長いですが、処理負荷も軽くていいんじゃないかと。
ただ、処理を増やしたのに処理負荷が減っている。動くべきは動いているのに何故?
追記
プロファイルカーブの処理も試し書きが一発OK。
ムービングで試しましたが、ディマーだけノンディマーになる。
もちろん、ディマーにだけディレイをかけられる。
なんか面白い。
どうやら処理の核は出来たらしい。
一晩寝かせてから総チェックします。
#Python #[Art-Net]