2022年2月 この範囲を時系列順で読む この範囲をファイルに出力する
ガラクタ週間が終わり、終日本業のデスクワークでした。
会場図面書いて、照明プランの概要まとめ、見積りというデスクワークの王道メニューです。
嫌いじゃないのですが、ガラクタネタが中途なのでソワソワします。
今やっているArt-Netは卓とデコーダが必要な作業なので、荷物も多いし広いスペースも必要です。しばらくはお休みかな。
明日から現場が続きますが、RaspberryPiだけ持って行って現在のソースをオブジェクト指向っぽく書く練習をしようかなぁ。
そうそう、製作というレベルではありませんが、ピンスポット用の照準器を増産しました。その実態は小型カメラ用の自在雲台を介して短いピカティニーレールをピンに取り付けるクランプです。
細かい部品を買い増しして組み立てるだけなので15分くらいの作業でしたが、なぜ思い立って作ったかと言えば数日後の現場で数年ぶりにピンを振ることになったからです。
鈍った腕でも対応出来そうな演目ですが、お年頃からくる目のコンディションでバインド照準器が使えませんので、ダットサイトなどの目印が遠くに見える照準器に頼らないとダメだと思われます。
このクランプは5-6年前に作った代物です。以前作った物は部下にあげてしまったので、余っていた部品で改めて自分用をこさえたワケです。
#RaspberryPi #Python
会場図面書いて、照明プランの概要まとめ、見積りというデスクワークの王道メニューです。
嫌いじゃないのですが、ガラクタネタが中途なのでソワソワします。
今やっているArt-Netは卓とデコーダが必要な作業なので、荷物も多いし広いスペースも必要です。しばらくはお休みかな。
明日から現場が続きますが、RaspberryPiだけ持って行って現在のソースをオブジェクト指向っぽく書く練習をしようかなぁ。
そうそう、製作というレベルではありませんが、ピンスポット用の照準器を増産しました。その実態は小型カメラ用の自在雲台を介して短いピカティニーレールをピンに取り付けるクランプです。
細かい部品を買い増しして組み立てるだけなので15分くらいの作業でしたが、なぜ思い立って作ったかと言えば数日後の現場で数年ぶりにピンを振ることになったからです。
鈍った腕でも対応出来そうな演目ですが、お年頃からくる目のコンディションでバインド照準器が使えませんので、ダットサイトなどの目印が遠くに見える照準器に頼らないとダメだと思われます。
このクランプは5-6年前に作った代物です。以前作った物は部下にあげてしまったので、余っていた部品で改めて自分用をこさえたワケです。
#RaspberryPi #Python
空き時間が少なかったのですが、Art-Netのエンコードを試してみました。
受信したバイナリをデコードし、パラメータをそのままにエンコードして送信です。単純な動作ですが、これが出来なきゃパッチマシンなど絶対無理というテストです。
卓からの8ユニバースをすべて処理したのですが、負荷の増加は2.5%くらいでした。十分に許容範囲で収まったのは良いことです。
パッチマシンは8in8outくらいを想定していますが、16in16outも可能だったりして。16ユニバース出る卓が無いので試せないし作ってもオーバースペックなので私は不要かな。機能全体を組み込んでから悩むことですが・・・。
今のところ1日1課題。
あとどれくらいの課題があるのかわかりませんが、納期はありませんのでノンビリいきましょう。ここまで出来れば、丁寧にclassライブラリにまとめ上げ、コメントに使い方を明記して後々も使える様にしておきましょう。
そういう意味ではキー操作やモニタ表示もclassライブラリにして汎用性を高めるのがいいですね。
と言いますか、このまま書き増しを続けるとソースコードがグチャグチャになって後で後悔しそうです。
私のメインはPICのアセンブラなのでANSI-Cの関数タイプっぽい書き方をしがちですが、Pythonならオブジェクト指向な書き方をしたいものです。最近、クラス、インスタンス、継承を使う意味と感覚がわかってきましたので、出来るだけそういった書き方をしていこうと思います。
以前は「継承」ってのが感覚的にわからんかったのですが、関数を束ねて新しい関数を作るだけだと簡単に考えればいいみたいです。ただ、関数は実体なのであっちこっちの関数から同じ関数を同時に呼ぶと衝突が起こります。解決には親関数の中で使う関数を親関数にとって専用にすればいいのですが、同じ様な関数を使うだけ書くのは面倒だしやらたとソースが大きくなるので、ひな形であるクラスから実体のインスタンスを作るという発想になったのだと最近ようやく「感覚的に」理解出来ました。
その筋の解説書を読むと「継承はオブジェクト指向という高貴な峰の頂」みたいな奇妙に美化した記述が多いのですが、その実態は「楽して俺様関数書きてぇ〜」って俗っぽい発想でした。美化した手段を書くだけで目的を書かない解説書が多いので感覚的にわからんかったのです。
#Python #[Art-Net]
受信したバイナリをデコードし、パラメータをそのままにエンコードして送信です。単純な動作ですが、これが出来なきゃパッチマシンなど絶対無理というテストです。
卓からの8ユニバースをすべて処理したのですが、負荷の増加は2.5%くらいでした。十分に許容範囲で収まったのは良いことです。
パッチマシンは8in8outくらいを想定していますが、16in16outも可能だったりして。16ユニバース出る卓が無いので試せないし作ってもオーバースペックなので私は不要かな。機能全体を組み込んでから悩むことですが・・・。
今のところ1日1課題。
あとどれくらいの課題があるのかわかりませんが、納期はありませんのでノンビリいきましょう。ここまで出来れば、丁寧にclassライブラリにまとめ上げ、コメントに使い方を明記して後々も使える様にしておきましょう。
そういう意味ではキー操作やモニタ表示もclassライブラリにして汎用性を高めるのがいいですね。
と言いますか、このまま書き増しを続けるとソースコードがグチャグチャになって後で後悔しそうです。
私のメインはPICのアセンブラなのでANSI-Cの関数タイプっぽい書き方をしがちですが、Pythonならオブジェクト指向な書き方をしたいものです。最近、クラス、インスタンス、継承を使う意味と感覚がわかってきましたので、出来るだけそういった書き方をしていこうと思います。
以前は「継承」ってのが感覚的にわからんかったのですが、関数を束ねて新しい関数を作るだけだと簡単に考えればいいみたいです。ただ、関数は実体なのであっちこっちの関数から同じ関数を同時に呼ぶと衝突が起こります。解決には親関数の中で使う関数を親関数にとって専用にすればいいのですが、同じ様な関数を使うだけ書くのは面倒だしやらたとソースが大きくなるので、ひな形であるクラスから実体のインスタンスを作るという発想になったのだと最近ようやく「感覚的に」理解出来ました。
その筋の解説書を読むと「継承はオブジェクト指向という高貴な峰の頂」みたいな奇妙に美化した記述が多いのですが、その実態は「楽して俺様関数書きてぇ〜」って俗っぽい発想でした。美化した手段を書くだけで目的を書かない解説書が多いので感覚的にわからんかったのです。
#Python #[Art-Net]
本業もボチボチ忙しくなってガラクタ週間も終わりを迎えようとしています。
現場と打ち合わせの合間にArt-Netです。
受信したバイナリをそのままの送信出来ないようでは先には進めませんが送信できない問題。
解決はしましたが、正規マニュアルや先達の書き込みに「これはちがう」とある設定で動いてしまいました。
基本環境:RaspberryPi4 Rasbian_buster Python3.7.3
ネットワークインターフェース:内臓LANポート(eth0)、USB-LANアダプタ(eth1)
IPアドレス:eth0もeth1もArt-Net用に設定済み。
試験環境:MAdot2でArt-Netを送出、RaspberryPiを経由、中華電機のArt-Netデコーダで受信、レガシーDMXをDoctorMXでモニタ。
処理内容:eth0で受信したArt-Netのバイナリをeth1で送信するだけ(これが出来なきゃ始まらない)。
-----
import socket
def artnet_rx_tx():
""" 基本パラメータセット """
RECV_HOST_NAME = ''
SENDTO_HOST_NAME = '255.255.255.255'
PORT = 6454
""" socket受信の設定 """
artnet_rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDPによるソケットを宣言(受信で使う)
artnet_rx_sock.setsockopt(socket.SOL_SOCKET, 25, str("eth0" + '\0').encode('utf-8')) #ソケットとNICを関連付け
artnet_rx_sock.bind((RECV_HOST_NAME, PORT)) #送信元とポートをソケットに関連付け この場合はどこからの送信でも受けるって意味になる
""" socket送信の設定 """
artnet_tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDPによるソケットを宣言(送信で使う)
artnet_tx_sock.setsockopt(socket.SOL_SOCKET, 25, str("eth1" + '\0').encode('utf-8')) #ソケットとNICを関連付け
artnet_tx_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #ソケットをブロードキャストとして使う宣言
""" 中継 """
for i in range(800): #繰り返し
artnet_rx_bytes, addr = artnet_rx_sock.recvfrom(1024) #受信処理
if len(artnet_rx_bytes) > 18: #受信データ長が最低長以上かを確認 下行とandで一文にしても意味は同じですがヘッダー長を下回った時にエラーになる
if artnet_rx_bytes[0:12] == b'Art-Net\x00\x00\x50\x00\x0e': #DMXの値データだけを選別 ヘッダーチェック
artnet_tx_sock.sendto(artnet_rx_bytes, (SENDTO_HOST_NAME, PORT)) #送信処理 ここがわからんで時間を喰う
""" 終了操作 """
artnet_rx_sock.close() #ソケットの仕舞い
artnet_tx_sock.close() #ソケットの仕舞い
※ 行頭の空白と#は全角で書いていますので、このままコピペするとエラーになります。
-----
for文による繰り返しで800回中継を行うテストソースです。
ポイントはBroadcastの送信先を指示する「SENDTO_HOST_NAME」です。socket.sendtoのパラメータです。「RECV_HOST_NAME」と同様に空白データを割り付けるベシとされるのが一般的ですが動きません。Broadcastアドレスを示す古い方法の'255.255.255.255'にしたところ稼働したという話です。
'2.255.255.255'や'10.255.255.255'でも稼働しましたが、'255.255.255.255'はゾーンの末尾アドレスを示すマジックナンバーらしく汎用性が高いと思われます。
動けばいいのですが、かなりの時間を喰ってしまい課題の残りが明日以降になりました。
ここまで出来ればパッチマップによる入れ替え処理を作ります。
壮大な繰り返し処理となりますので、どれだけ簡素に出来るかがカギになります。
#Python #[Art-Net]
現場と打ち合わせの合間にArt-Netです。
受信したバイナリをそのままの送信出来ないようでは先には進めませんが送信できない問題。
解決はしましたが、正規マニュアルや先達の書き込みに「これはちがう」とある設定で動いてしまいました。
基本環境:RaspberryPi4 Rasbian_buster Python3.7.3
ネットワークインターフェース:内臓LANポート(eth0)、USB-LANアダプタ(eth1)
IPアドレス:eth0もeth1もArt-Net用に設定済み。
試験環境:MAdot2でArt-Netを送出、RaspberryPiを経由、中華電機のArt-Netデコーダで受信、レガシーDMXをDoctorMXでモニタ。
処理内容:eth0で受信したArt-Netのバイナリをeth1で送信するだけ(これが出来なきゃ始まらない)。
-----
import socket
def artnet_rx_tx():
""" 基本パラメータセット """
RECV_HOST_NAME = ''
SENDTO_HOST_NAME = '255.255.255.255'
PORT = 6454
""" socket受信の設定 """
artnet_rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDPによるソケットを宣言(受信で使う)
artnet_rx_sock.setsockopt(socket.SOL_SOCKET, 25, str("eth0" + '\0').encode('utf-8')) #ソケットとNICを関連付け
artnet_rx_sock.bind((RECV_HOST_NAME, PORT)) #送信元とポートをソケットに関連付け この場合はどこからの送信でも受けるって意味になる
""" socket送信の設定 """
artnet_tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDPによるソケットを宣言(送信で使う)
artnet_tx_sock.setsockopt(socket.SOL_SOCKET, 25, str("eth1" + '\0').encode('utf-8')) #ソケットとNICを関連付け
artnet_tx_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #ソケットをブロードキャストとして使う宣言
""" 中継 """
for i in range(800): #繰り返し
artnet_rx_bytes, addr = artnet_rx_sock.recvfrom(1024) #受信処理
if len(artnet_rx_bytes) > 18: #受信データ長が最低長以上かを確認 下行とandで一文にしても意味は同じですがヘッダー長を下回った時にエラーになる
if artnet_rx_bytes[0:12] == b'Art-Net\x00\x00\x50\x00\x0e': #DMXの値データだけを選別 ヘッダーチェック
artnet_tx_sock.sendto(artnet_rx_bytes, (SENDTO_HOST_NAME, PORT)) #送信処理 ここがわからんで時間を喰う
""" 終了操作 """
artnet_rx_sock.close() #ソケットの仕舞い
artnet_tx_sock.close() #ソケットの仕舞い
※ 行頭の空白と#は全角で書いていますので、このままコピペするとエラーになります。
-----
for文による繰り返しで800回中継を行うテストソースです。
ポイントはBroadcastの送信先を指示する「SENDTO_HOST_NAME」です。socket.sendtoのパラメータです。「RECV_HOST_NAME」と同様に空白データを割り付けるベシとされるのが一般的ですが動きません。Broadcastアドレスを示す古い方法の'255.255.255.255'にしたところ稼働したという話です。
'2.255.255.255'や'10.255.255.255'でも稼働しましたが、'255.255.255.255'はゾーンの末尾アドレスを示すマジックナンバーらしく汎用性が高いと思われます。
動けばいいのですが、かなりの時間を喰ってしまい課題の残りが明日以降になりました。
ここまで出来ればパッチマップによる入れ替え処理を作ります。
壮大な繰り返し処理となりますので、どれだけ簡素に出来るかがカギになります。
#Python #[Art-Net]
オレメモです。
パッチマップ(出力側ベース)
・フリーフェーダースロット
・ディレイ:<0>ならスルー、<1-255>ならディレイ
・ユニバース(入力参照)
・スロット(入力参照)
・カーブプロファイル:<0>ならスルー、<1-511>なら以下とする
>カーブプロファイル<1-255>はノンディマーとしてしきい値とする
>カーブプロファイル<256-511>はカーププロファイルマップを参照する
#[Art-Net]
パッチマップ(出力側ベース)
・フリーフェーダースロット
・ディレイ:<0>ならスルー、<1-255>ならディレイ
・ユニバース(入力参照)
・スロット(入力参照)
・カーブプロファイル:<0>ならスルー、<1-511>なら以下とする
>カーブプロファイル<1-255>はノンディマーとしてしきい値とする
>カーブプロファイル<256-511>はカーププロファイルマップを参照する
#[Art-Net]
Art-Netの受信に成功して処理負荷に余裕もあるとなれば落としどころをどうするか!?って話にもなるワケです。最大の望みはディレイ機能とカーブプロファイル機能を持ったパッチマシンですが、欲を出し過ぎたら頓挫します。
さてさて、どこまで行けるのでしょう。
お試しに次ぐお試しでとっ散らかったソースコードを整理整頓し、受信モニタとしてまとめ上げてからの話ですが、受信したArt-Netを送信する試験をしましょう。
ただし、単にリレーするだけでは面白くないし処理負荷の確認にもなりません。受信をデコードし、1対1のパッチ処理をし、エンコードして送信することにします。1対1とはいえマッピングデータ用いた入れ替えをすれば最終形の負荷に近くなると思います。ここまでやれば天井が見えてくるでしょう。
もしRaspberryPiには荷が重いならPCで動かせばいいって話もあります。今のところRaspberryPiというよりDebian上のPython3.7で動く様に作っていますのでPCでも動くと思います。レガシーDMXを搭載せずにいる理由の一つでもあります。
今どきのムービング卓はArt-Netを出しますし、Art-Netのデコーダーは既製品が沢山ありますので、レガシーDMXまで作らなくてもいいかなぁ~なんて思ってます。専用基板を作る初期投資がキツイってのが一番大きいですが・・・
#Python #[Art-Net]
さてさて、どこまで行けるのでしょう。
お試しに次ぐお試しでとっ散らかったソースコードを整理整頓し、受信モニタとしてまとめ上げてからの話ですが、受信したArt-Netを送信する試験をしましょう。
ただし、単にリレーするだけでは面白くないし処理負荷の確認にもなりません。受信をデコードし、1対1のパッチ処理をし、エンコードして送信することにします。1対1とはいえマッピングデータ用いた入れ替えをすれば最終形の負荷に近くなると思います。ここまでやれば天井が見えてくるでしょう。
もしRaspberryPiには荷が重いならPCで動かせばいいって話もあります。今のところRaspberryPiというよりDebian上のPython3.7で動く様に作っていますのでPCでも動くと思います。レガシーDMXを搭載せずにいる理由の一つでもあります。
今どきのムービング卓はArt-Netを出しますし、Art-Netのデコーダーは既製品が沢山ありますので、レガシーDMXまで作らなくてもいいかなぁ~なんて思ってます。専用基板を作る初期投資がキツイってのが一番大きいですが・・・
#Python #[Art-Net]
Art-Netの受信に成功しました。
先達のサンプルコードをコピペしてPort番号を書き換えただけで一発OK。積年の成果が出て良かったのですが、あまりにも簡単だったので肩透かし。
複数のNICを使い分けるsocketの設定は先達情報に何パターンかありますが、Rasbian上のPythonに合うパターンを見つけるのに少し時間がかかったかもしれません。
今は卓のエフェクトエンジンで出力したデータが画面に流れております。4096chのディマーを256bpmの正弦波で動かしています。アホか。
テストデータはMAdot2からですが、SequenceとPhysicalにデータが出ていました。
Sequenceは単純なインクリメント情報、Physicalは卓内のUnivres番号です。
送信を作るときにはこの流儀を真似しましょう。
ただ、MAdot2はOpCode<0x5000>以外のArt-Netパケットも出しており、socketで受信したバイナリが19バイト以上で頭12バイトがb'Art-Net\x00\x00\x50\x00\x0E'であることを最初にチェックしないといけません。当初はバイト長も見ずにb'Art-Net\x00'だけでチェックしていたのでデコード処理でエラーが頻発でした。OpCodeによってデータ長も内容も違うので当然の結果ですが、マルチキャストなら<0x5000>以外のOpCodeは出さないと先入観で思ってしまったようです。よくないですね。
8ユニバースを受信させています。すべてのユニバースをデコード処理までしていますが、思った以上に軽々動いています。
Sequenceをキーに連続性をチェックしましたが読み飛ばしもしていないようです。
今のところは先日作った画面ではなくすべてのパラメータを表示するチェック用の画面に表示していますが、先日作った画面を同時に動かしてもCPU負荷は45%程度です。最大値は400%(100%×4コア)なのでまだ余裕があります。
#Python #[Art-Net]
先達のサンプルコードをコピペしてPort番号を書き換えただけで一発OK。積年の成果が出て良かったのですが、あまりにも簡単だったので肩透かし。
複数のNICを使い分けるsocketの設定は先達情報に何パターンかありますが、Rasbian上のPythonに合うパターンを見つけるのに少し時間がかかったかもしれません。
今は卓のエフェクトエンジンで出力したデータが画面に流れております。4096chのディマーを256bpmの正弦波で動かしています。アホか。
テストデータはMAdot2からですが、SequenceとPhysicalにデータが出ていました。
Sequenceは単純なインクリメント情報、Physicalは卓内のUnivres番号です。
送信を作るときにはこの流儀を真似しましょう。
ただ、MAdot2はOpCode<0x5000>以外のArt-Netパケットも出しており、socketで受信したバイナリが19バイト以上で頭12バイトがb'Art-Net\x00\x00\x50\x00\x0E'であることを最初にチェックしないといけません。当初はバイト長も見ずにb'Art-Net\x00'だけでチェックしていたのでデコード処理でエラーが頻発でした。OpCodeによってデータ長も内容も違うので当然の結果ですが、マルチキャストなら<0x5000>以外のOpCodeは出さないと先入観で思ってしまったようです。よくないですね。
8ユニバースを受信させています。すべてのユニバースをデコード処理までしていますが、思った以上に軽々動いています。
Sequenceをキーに連続性をチェックしましたが読み飛ばしもしていないようです。
今のところは先日作った画面ではなくすべてのパラメータを表示するチェック用の画面に表示していますが、先日作った画面を同時に動かしてもCPU負荷は45%程度です。最大値は400%(100%×4コア)なのでまだ余裕があります。
#Python #[Art-Net]
雪に隠れていた縁石に自家用車のタイヤをやられました。
鋭利に割れていたのでサイドウォールがパックリ。雪は滑るだけが危険要素ぢゃないようです。
サイドウォールは修理が出来ないので交換ですが、冬タイヤはトップシーズンのために割高な物しか手に入らず懐も寒くなりました。
運が悪かったと思うしかありませんが、テンション下がるわー。
開発が順調でテンションが上がっているので丁度いいのかもしれませんけど。
#日常
鋭利に割れていたのでサイドウォールがパックリ。雪は滑るだけが危険要素ぢゃないようです。
サイドウォールは修理が出来ないので交換ですが、冬タイヤはトップシーズンのために割高な物しか手に入らず懐も寒くなりました。
運が悪かったと思うしかありませんが、テンション下がるわー。
開発が順調でテンションが上がっているので丁度いいのかもしれませんけど。
#日常
RaspberryPiを触っていて思うのですが、普通のPCにもRaspberryPi並みのGPIOがあればいいなと。
RaspberryPi仕様のGPIOがベストって意味ではありませんが、PCにもローレベルのインターフェースがあったら制御で便利に使えるのになと。
もちろん存在していますが、あまりにニッチ過ぎて情報が少ないために敷居が高いのです。
主にUSB接続ですが、PCI-eボード1枚にI2C、SPI、USART、GPIOが「これでもか!」ってくらい載ってるのがあったら欲しいかも。
#妄想
RaspberryPi仕様のGPIOがベストって意味ではありませんが、PCにもローレベルのインターフェースがあったら制御で便利に使えるのになと。
もちろん存在していますが、あまりにニッチ過ぎて情報が少ないために敷居が高いのです。
主にUSB接続ですが、PCI-eボード1枚にI2C、SPI、USART、GPIOが「これでもか!」ってくらい載ってるのがあったら欲しいかも。
#妄想
Art-Netの受信データをデコードする処理を書いてみました。
製作環境はRspberryPi4、Rasbian_buster、Python 3.7.3です。
------
import numpy as np
class coding:
def decode(self, artnet_packet):
""" Art-Netのbyte列を要素に分解する """
id = artnet_packet[0:8]
opcode = int.from_bytes(artnet_packet[8:10], 'little')
prover = int.from_bytes(artnet_packet[10:12], 'big')
sequence = int.from_bytes(artnet_packet[12:13], 'little')
physical = int.from_bytes(artnet_packet[13:14], 'little')
subuni = int.from_bytes(artnet_packet[14:15], 'little')
sub = subuni // 16
uni = subuni % 16
net = int.from_bytes(artnet_packet[15:16], 'little')
length = int.from_bytes(artnet_packet[16:18], 'big')
data = np.frombuffer(artnet_packet, dtype=np.uint8, count=length, offset=18)
return (id, opcode, prover, sequence, physical, net, sub, uni, length, data)
if __name__ == '__main__':
an = coding()
id, opcode, prover, sequence, physical, net, sub, uni, length, data_uint8 = an.decode(test_artnet_packet)
※ 行頭の空白には全角を使っています。
------
test_artnet_packetに受信データを入れ、codingのインスタンスanでdecodeを呼び出します。
書いてみたら案外スッキリした物になったので記念に掲載しました。
socketで受信するのはバイナリデータ(Pythonで言うところのバイト列)ですが、これを一発でnumpy.arrayに変換してくれるnumpy.frombufferは便利です。
int.from_bytesもバイト列をエンディアン指定でint数に一発変換してくれて便利です。
私はPICマイコンと協調させて使うことが多いので、こういった機能があると助かります。
上記ですとdataの戻り値がnumpy.uint8ですが、計算するためにはnumpy.uint16の方が良いと思います。
data_uint16 = data.astype(np.uint16)
とかで型変換するといいかもしれません。
#Python #[Art-Net]
製作環境はRspberryPi4、Rasbian_buster、Python 3.7.3です。
------
import numpy as np
class coding:
def decode(self, artnet_packet):
""" Art-Netのbyte列を要素に分解する """
id = artnet_packet[0:8]
opcode = int.from_bytes(artnet_packet[8:10], 'little')
prover = int.from_bytes(artnet_packet[10:12], 'big')
sequence = int.from_bytes(artnet_packet[12:13], 'little')
physical = int.from_bytes(artnet_packet[13:14], 'little')
subuni = int.from_bytes(artnet_packet[14:15], 'little')
sub = subuni // 16
uni = subuni % 16
net = int.from_bytes(artnet_packet[15:16], 'little')
length = int.from_bytes(artnet_packet[16:18], 'big')
data = np.frombuffer(artnet_packet, dtype=np.uint8, count=length, offset=18)
return (id, opcode, prover, sequence, physical, net, sub, uni, length, data)
if __name__ == '__main__':
an = coding()
id, opcode, prover, sequence, physical, net, sub, uni, length, data_uint8 = an.decode(test_artnet_packet)
※ 行頭の空白には全角を使っています。
------
test_artnet_packetに受信データを入れ、codingのインスタンスanでdecodeを呼び出します。
書いてみたら案外スッキリした物になったので記念に掲載しました。
socketで受信するのはバイナリデータ(Pythonで言うところのバイト列)ですが、これを一発でnumpy.arrayに変換してくれるnumpy.frombufferは便利です。
int.from_bytesもバイト列をエンディアン指定でint数に一発変換してくれて便利です。
私はPICマイコンと協調させて使うことが多いので、こういった機能があると助かります。
上記ですとdataの戻り値がnumpy.uint8ですが、計算するためにはnumpy.uint16の方が良いと思います。
data_uint16 = data.astype(np.uint16)
とかで型変換するといいかもしれません。
#Python #[Art-Net]
Art-Netのアプリは画面表示とキー操作まで一応の完成をみました。
キー操作はレスポンスに少しムラがあるので改善したい点です。使えるレベルなので今のところは将来課題としておきますが、ユーザーがご機嫌をうかがいながら使うユーザーインターフェースは大嫌いなのでとても重要です。
余談ですが、売れている卓とそうでもない卓の違いにはこういった点の僅かなストレスの差もあります。卓は手段としての道具ですが、国内メーカーはカタログスペックばかり求めて手に馴染む道具を作ろうとしない。買うのは使う人ではありませんから仕方ないことでもありますが、国産のホール卓がダメな点です。国産で唯一、松村さんの卓にはこういったストレスが少ないのですが・・・。
とまぁ愚痴はおいといて、これで本丸であるArt-Netの受信に取り掛かれます。
単純な受信は別回しするThread内のsocketで受けるだけなので難しくないと思うのですが、パケットのデコードが少し面倒かもしれません。Art-Netのパケットはバイト列ですが、これらをPythonで扱いやすい様に分解して変換しなければなりません。Pythonはバイト型の扱いが少し苦手ですし、パケットにはアスキーテキスト、LSBの2バイト数、MSBの2バイト数、バイト型が混在しているので、よく考えて作らないといけません。実行回数が多い処理なだけに軽さも重要です。
#[Art-Net] #Python
キー操作はレスポンスに少しムラがあるので改善したい点です。使えるレベルなので今のところは将来課題としておきますが、ユーザーがご機嫌をうかがいながら使うユーザーインターフェースは大嫌いなのでとても重要です。
余談ですが、売れている卓とそうでもない卓の違いにはこういった点の僅かなストレスの差もあります。卓は手段としての道具ですが、国内メーカーはカタログスペックばかり求めて手に馴染む道具を作ろうとしない。買うのは使う人ではありませんから仕方ないことでもありますが、国産のホール卓がダメな点です。国産で唯一、松村さんの卓にはこういったストレスが少ないのですが・・・。
とまぁ愚痴はおいといて、これで本丸であるArt-Netの受信に取り掛かれます。
単純な受信は別回しするThread内のsocketで受けるだけなので難しくないと思うのですが、パケットのデコードが少し面倒かもしれません。Art-Netのパケットはバイト列ですが、これらをPythonで扱いやすい様に分解して変換しなければなりません。Pythonはバイト型の扱いが少し苦手ですし、パケットにはアスキーテキスト、LSBの2バイト数、MSBの2バイト数、バイト型が混在しているので、よく考えて作らないといけません。実行回数が多い処理なだけに軽さも重要です。
#[Art-Net] #Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131