-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
バイト列の扱い方について #635
Comments
数値のlistとしてのバイト列表現 <-> 文字列 の変換としては以下のようにかける $ (coerce "あいう" cons)
(227 129 130 227 129 132 227 129 134)
$ (coerce '(227 129 130 227 129 132 227 129 134) string)
"あいう" |
文字列のバイト列が所定の長さになるように0パディングするには以下のようにかける 4.irteusgl$ (setq byte-array (coerce "あいう" cons))
(227 129 130 227 129 132 227 129 134)
5.irteusgl$ (setq target-length 64)
64
6.irteusgl$ (concatenate cons byte-array (make-list (- target-length (length byte-array)) :initial-element 0))
(227 129 130 227 129 132 227 129 134 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) |
rosのmessage型でuint8[]に渡す場合、stringで渡すようになっている。 |
@k-okada Is there any files related to byte array parsing and generating? If so, I would like to add some utility functions to there like (defun padding-byte-array (byte-array target-length)
(concatenate cons byte-array (make-list (- target-length (length byte-array)) :initial-element 0))) according to the review in jsk-ros-pkg/jsk_robot#1830 |
最初のコメントしか見ていないけど,こういうこと?
use https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ to convert hex to float |
そんな感じのことがしたいのですが、バイト列をパースする際にバイトオーダー(LSBかMSBか)やsigned or unsigned, 精度等を指定してパースをしたいと考えていて、かつこのようなバイト列と数値との変換はeuslispの数値表現とは必ずしも一致しないために何らかのパース処理が必要かと考えています。 バイナリデータの読み込みを行う際にはファイルからにせよ他のプロセスからにせよこのような類の処理が必要になるのでなにかしらすでに実装されていればその部分の処理を利用したり、追加・変更したいと思っていて、既存のeuslispにはそのようなライブラリが存在するでしょうか? あと、この例における
|
% 2個上の例題間違えていたので直しました. で,peek/poke は結局eusの型でしか出てこないので,float/double やbyte/int/long は対応できるけど,singned / unsigned は対応出来なそうですね.またバイトオーダもCPU依存になりそう. とは言え,バイトオーダはLSBでsigned で,と運用する(少なくともeusが絡む場合は)としちゃえば,問題ないんじゃない.と思うのと,このパースするための情報はどうやって渡すの?別途2つのシステム間でフォーマット情報を受け渡しするの? |
なるほど、理解しました。smart_device_ros (まだ名前変えてない) で絡むマシンは ESP32 も x86_64 も LSBっぽいので結局そのままでいいかもです。 パース情報はこのリポジトリでは C用、Python用で パーサ/シリアライザ を個別に書いています。十分にながければStringでJSONみたいなやつ渡してしまいたいのですが組み込み側で簡単なふうに処理を書いてしまいました。 |
ちなみにrosserial はどうしているのかな。
…--
◉ Kei Okada
2023年6月28日(水) 9:30 Koki Shinjo ***@***.***>:
これは,
https://github.com/euslisp/EusLisp/blob/9b1a896af3dad4a245d97d745130939ca2814f6b/lisp/c/sysfunc.c#L642-L676
なので,普通にCPU上のバイト列なんだとおもいます.jmanual
の記述はC言語内でLispオブジェクトの表現の説明なので,CPU上のバイト列とは違うのかな.
なるほど、理解しました。smart_device_ros (まだ名前変えてない)
<https://github.com/sktometometo/esp_now_ros> で絡むマシンは ESP32 も x86_64 も
LSBっぽいので結局そのままでいいかもです。
パース情報はこのリポジトリでは C用、Python用で パーサ/シリアライザ
を個別に書いています。十分にながければStringでJSONみたいなやつ渡してしまいたいのですが組み込み側で簡単なふうに処理を書いてしまいました。
—
Reply to this email directly, view it on GitHub
<#635 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADYNXFNJXHD63DWGXXPLXLXNN3IPANCNFSM6AAAAAAZU54WKY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
ここでは ros-drivers/rosserial#569 は使用していないです。ESP32は本体と優先で接続して、ESP32が他のデバイスと無線通信するインターフェースになっているので、 イメージ的には PC -- USB -- ESP32 interface デバイス (このスケッチ を書き込んだM5Stack) .... ESP_NOW ... ESP32 other device みたいな接続になっています。 |
あ,そこではなくて,rosserial はマイコンとPCの間の通信はどうしているか?ということでした. 手書きでパーサを書いてよいのは,基本は送られるデータ型が決まっている場合で,それ以外は使わないで運用してください.という場合が良いです.手書きでバーサを書くけど仕様を決めてあるので後はユーザで任意のデータの送受信をしてください,は結局使われないです. あるいは,std_msgs だけは対応します,とか,自分で簡易的なフォーマット決めて最大4個のリストで,ネストは許さなくて,文字列は255固定,とか,で,"isfd"+binary(123)+string("hello")+binary(123.4)+binary(24555.4544) みたいなストリングを送るとか, と思ったけど,使っているのは ちなみに,こういう風にパケットのデザインをしている場合はちゃんとその情報をhttps://tldp.org/LDP/tlk/net/net.html みたいに図解しておきましょう. |
JSONか所定のフォーマットを前に記述するやり方でやってみます。 データフィールドの並びだけでなく、そのパケットが何用途向けなのかがわからないと、float x 3 の並びのセンサデータがセンサの認識したオブジェクトの位置なのか、加速度センサの出力した三軸加速度なのかがわからなくて、パケットのデータが何であるかを説明するフィールドそのものは必要かと思うので、そうなるとフレームの構成としては | パケットの説明を示すフィールド | データ部分の構造を示すフィールド | データ部分 | のような構成にしてみようと思います。 |
ただ、シリアライザやパーサの実装そのものは共通化できる一方で、パース後のデータを利用するプログラムは自分の使いたいパケットの説明に対応したパース後のデータ構造を知っている必要がある気がしていて、それは結局README.mdに今記述しているフレームの構造そのものではないかと思いました。 そう考えるとフレームのうちデータフィールドの構造を記述している部分は冗長で、その結果いまのような形をとっている部分はありました。 フレームの説明とパース結果のなんとなくのデータから自分が使いたいデータ形式への一般的な変換方法があれば、プログラム側で詳細なデータ構造について知っている必要はないのかな |
rosserialで上記のESP_NOWパケットのbodyを直にpublishしているので、subscribeするプログラムで body をなんらかの形でパースする必要はあります。 今のPythonプログラムではユーザーはこれらのトピックを直にやりとりせず、 |
要求機能を正確に把握していないため今回使えるかは分からないのですが、body部分のフォーマットをROSのトピックのパケットのフォーマットと共通にして、ROSのトピックのデシリアライザを使えば、bitから任意のデータ形式への変換・publishを一般的に行えるのではないかと思いました. |
あ、ROSのトピックのデシリアライザの話は既に岡田先生のコメントで出ていて、ROSのトピックはデータフィールドの構造を記述している部分が冗長だから別の手法を検討しているという流れになっていることを見落としていました。 |
結局README.mdに今記述しているフレームの構造そのものではないかと思いました
僕の言っている図解はこのREADME.md の情報でした。で、その先に2つの方向性があって、
1)自分の分析では世の中のEmbededSensorsというのはこういうカテゴリの使い方に整理されるので、こういう風に準備しています。現状でセンサとして実装されているのはこの部分です。(bluetooth方式)
2)EmbededSensors(でもないかアクチュエーションではないけど情報提示はするからDevicesになるのでしょうか?)は無限に考えられるので、ユーザに追加を足してもらう方式です。その場合はこの1つのファイルでメッセージを定義すれば組み込み側のシリアライズとPC側のデシリアライズはシステムが行ってくれます(rosserial
方式)
前者なら今のREADMEでOKか、目の前のデバイスのリストで作り上げたものであはなく、トップダウンに説明できているか確認で、後者であると何らかのシリアライズ/デシリアイズを行うべきでしょう。メッセージファイル(IDLファイル)を作って対応するか、JSONみたいにデータにフォーマットも仕込んでおくか。
また、README.mdでデータの種類と意味を定義しているので、その情報でトピックを流せばよい気がしました。わざわざbinaryのデータを流すのは、esp_now_rosの外側で、バイナリデータの種類と意味の解釈を任せている、という意味合いに見えているんだけど、その意味と解釈自体はesp_now_rosのREADME.mdに書いてあるのは不整合に見えました。そもそもの原因は、意味と解釈はデバイス側に書き込まれているわけで、意味と解釈はeps_now_ros側で吸収しないといけないように思います。つまり、ならんかのテキスト/数値のデータでパブリッシュするのが良いように見えます。
| パケットの説明を示すフィールド | データ部分の構造を示すフィールド | データ部分 |
は既存の仕様がありそうな気がするけど、具体的に何?と言われると出てこないけど。pickle とかはそうなのかな。
2023年6月29日(木) 9:04 Koki Shinjo ***@***.***>:
… と思ったけど,使っているのは
https://github.com/sktometometo/esp_now_ros/blob/c0807250bfb6671aa8d5045378820ea451a5c7dc/python/esp_now_ros/packet_parser.py
なのかな.ここでパースしていれば,eusとepsの通信はrosのメッセージ経由でbinaryをパースする必要はないのでは.
rosserialで上記のESP_NOWパケットのbodyを直にpublishしているので、subscribeするプログラムで body
をなんらかの形でパースする必要はあります。
( /esp_now_ros/send トピックと /esp_now_ros/recv トピック )
今のPythonプログラムではユーザーはこれらのトピックを直にやりとりせず、ESPNOWROSInterface
というクラスを通じてトピックのやり取りをするようにしているのですが、
https://github.com/sktometometo/esp_now_ros/blob/c0807250bfb6671aa8d5045378820ea451a5c7dc/node_scripts/esp_now_packet_printer.py#L9-L11
のように結局 parse_packet() 関数でデータをパースする必要があります。
—
Reply to this email directly, view it on GitHub
<#635 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADYNXELIUJIB7FRXJUCD33XNTBATANCNFSM6AAAAAAZU54WKY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
euslisp で Python3 の bytes 型のようにバイト列を扱う場合、どのような表現方法があるでしょうか?
また、バイト列をパースして数値や文字列へパースしたり、また数値や文字列をバイト列へエンコードする際に、Pythonでのstructモジュールに当たるようなユーティリティ関数やライブラリがあれば使いたいです。
The text was updated successfully, but these errors were encountered: