fix(crane_robot_receiver): byte 2 をチェックサムとして扱う誤った前提を除去する - #1396
Merged
Merged
Conversation
Member
Author
|
チェックサムの計算方法が多分違う |
HansRobo
force-pushed
the
fix/receiver-checksum-validation
branch
from
September 17, 2026 08:50
179af75 to
98a20ee
Compare
## 背景
当初このブランチは「実装済みなのに呼ばれていないチェックサム検証を有効化する」
修正だった。しかし実機ファームウェアの一次ソースを確認した結果、
フィードバックパケットの byte 2 はチェックサムではないことが判明したため、
修正内容を全面的に差し替える。
- G474_Orion_main `Core/Src/ai_comm.c` sendRobotInfo():
`buf[2] = 10; // CRC, 10:dummy`
- Orion_CM4 `cm4/bridge/robot_feedback_packet.h`:
「実機は定数 10 を書くだけで、実際のチェックサムは計算していない。検証に使ってはいけない」
- Orion_CM4 `doc/feedback_packet.md`:
「byte 2 はチェックサムではありません」「受信側でこの判定を有効にしてはいけません」
byte 2 を検証すると `readRawByte(buf, 2)` は常に 10、`computeChecksum(buf)` は
byte 3..127 の総和下位 8bit となり、実機フィードバックが全パケット破棄される。
電圧・エラー・ボールセンサ・odom・診断がすべて停止する致命的リグレッションだった。
## 修正内容
誤った前提を再発させている3点を取り除く。
- `robot_feedback_protocol.hpp`
- `computeChecksum()` と `PacketValidationResult::checksum_valid` を削除
- `offset::CHECKSUM` を `offset::DUMMY_CRC` にリネームし、ファームの出典を明記
- `validatePacket()` に `received_size` を追加。受信バッファは BUFFER_SIZE (2048) 長の
使い回しなので `buffer.size()` をパケット長と見なすと常に size_valid=false になる
- `robot_receiver_node.cpp`
- `onReceive` の独自検証を `validatePacket()` へ一本化(検証定義の二重化を解消)
- `checksum_error_count_` を削除
- `crane_msgs/msg/RobotFeedback.msg` / `diagnostic_publisher.cpp`
- 構造的に永久に 0 である `checksum_error_count` を削除
- `scenario_test/inject_feedback.py`
- byte 2 に本物のチェックサムを書いていたのを実機と同じ定数 10 に変更。
これが「sim では緑、実機だけ死ぬ」状態を作っていた
- `test_robot_feedback_protocol.cpp`
- 存在しないプロトコルを検証していたチェックサムのテストを削除
- byte 2 の値が検証結果に影響しないことの回帰テストを追加
- 2048 バイトバッファに 128 バイト届く実受信形状のテストを追加
HansRobo
force-pushed
the
fix/receiver-checksum-validation
branch
from
September 17, 2026 09:07
98a20ee to
ad4a49f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
このPRは当初の内容から全面的に差し替えました。
当初は「実装済みなのに呼ばれていないチェックサム検証を有効化する」修正でしたが、実機ファームウェアの一次ソースを確認した結果、フィードバックパケットの byte 2 はチェックサムではないことが判明しました。当初の修正はマージすると実機フィードバックが全滅する致命的リグレッションだったため、修正内容を「誤った前提そのものの除去」へ差し替えます。
根拠(一次ソース)
G474_Orion_mainCore/Src/ai_comm.csendRobotInfo()buf[2] = 10; // CRC, 10:dummyOrion_CM4cm4/bridge/robot_feedback_packet.hOrion_CM4doc/feedback_packet.mdbyte 2 を検証すると
readRawByte(buf, 2)は常に10、computeChecksum(buf)は byte 3..127 の総和下位 8bit となり、両者が一致することは事実上ありません。結果として実機フィードバックが全パケット破棄され、電圧・エラーID・ボールセンサ・odom・診断がすべて停止します。crane_robot_skills/src/single_ball_placement.cppのボール保持判定もball_sensorに依存しているため機能しなくなります。問題の本質
当初の誤修正は偶然生まれたものではなく、誤検出を誘発する仕掛けがコード側に3つ残っていたことが原因です。これを放置すると同じ修正が再提出されます。
robot_feedback_protocol.hppにcomputeChecksum()/PacketValidationResult::checksum_validが「正しいのに未使用の API」の顔で残っていたscenario_test/inject_feedback.pyが byte 2 に本物のチェックサムを書いていた → 誤った修正が sim では全て緑、実機でだけ死ぬtest_robot_feedback_protocol.cppが存在しないプロトコルを緑で守っていた修正内容
crane_robot_receiver/include/crane_robot_receiver/robot_feedback_protocol.hppcomputeChecksum()とPacketValidationResult::checksum_validを削除offset::CHECKSUM→offset::DUMMY_CRCにリネームし、ファームの出典をコメントで明記。DUMMY_CRC_VALUE = 10を追加validatePacket()にreceived_size引数を追加受信バッファは
BUFFER_SIZE(2048) 長の使い回しで渡されるため、従来のbuffer.size() == PACKET_SIZEは実受信経路では常に false でした。validatePacket()は事実上テスト内でしか成立しない死にコードだったため、素直に配線すると全パケットが落ちる状態でした。crane_robot_receiver/src/robot_receiver_node.cpponReceiveの独自検証をvalidatePacket()へ一本化(検証定義の二重化を解消)checksum_error_count_を削除crane_msgs/msg/RobotFeedback.msg/diagnostic_publisher.cppchecksum_error_countを削除(常に0の診断は無いより悪いため)gh search code --owner ibis-ssl "checksum_error_count"で org 内を確認し、crane 以外に consumer が無いことを確認済みscenario_test/inject_feedback.py10に変更crane_robot_receiver/test/test_robot_feedback_protocol.cppレビュー観点
ai_comm.c/feedback_packet.md)の解釈が正しいかvalidatePacket()のreceived_size追加により、onReceiveの判定が従来と等価かchecksum_error_countの msg フィールド削除による影響範囲別途対応(このPRには含めない)
一次ソースとの突き合わせで、チェックサムとは独立したレイアウト不整合も検出しています。別PRで対応します。
tx_cycle_count(feedback 送信ごとに++)ball_detection[2]buf[28] = 0; // unusedball_detection[3](常に0)ball_sensorはball_detection[0](byte 12)のみを見ているため制御への影響はありませんが、publish 値は誤っています。また byte 14 のtx_cycle_countこそフィードバック側のパケットロス検知に使うべき連番です。現在のcounter_jump_countは byte 3 を使っていますが、byte 3 は実機ではai_cmd->check_counterの反射にすぎず、さらにcrane_sender/src/ibis_sender_node.cppがcounter_を 0..200 で折り返すのに対し受信側は uint8 のlast + 1を期待しているため、折り返しのたびに誤カウントします。