Skip to content

Fix CRC mismatch on HG LowCmd/LowState caused by struct padding#31

Open
yaodeng-anitron wants to merge 1 commit into
unitreerobotics:mainfrom
yaodeng-anitron:fix/hg-crc-padding
Open

Fix CRC mismatch on HG LowCmd/LowState caused by struct padding#31
yaodeng-anitron wants to merge 1 commit into
unitreerobotics:mainfrom
yaodeng-anitron:fix/hg-crc-padding

Conversation

@yaodeng-anitron
Copy link
Copy Markdown

Summary

The current CRC computation for unitree_hg::msg::dds_::LowCmd_ /LowState_ reinterprets the in-memory struct as a uint32_t[]:

  msg_.crc() = crc32_core((uint32_t*)&msg_, (sizeof(MsgType)>>2)-1);                                              

MotorCmd_ / MotorState_ lay out as uint8_t mode followed by float, so the C++ compiler inserts 3 bytes of alignment padding. Those padding bytes are not guaranteed zero (the IDL setters only touch the named fields), so the CRC walks bytes the firmware never sees and disagrees with the firmware's CRC computed from the wire-serialized frame.

Symptom: firmware silently drops the frame; motors never go under user control — motor_cmd[i].mode = 1 is sent but LowState.motor_state[i].mode stays 0.

The Python SDK (unitree_sdk2py.utils.crc.CRC) already does the righ thing: pack into a deterministic wire-format buffer first, then CRC. This PR brings the C++ SDK into alignment with the Python SDK and the firmware.

Change

  • New crc32_core overloads for unitree_hg::msg::dds_::LowCmd_ and LowState_ in include/unitree/dds_wrapper/common/crc.h. They build a packed buffer with explicit zero padding matching the Python format strings:
    • LowCmd_: '<2B2x' + 'B3x5fI' * 35 + '5I' → 1004 B, CRC over 1000 B (250 u32 words)
    • LowState_: '<2I2B2xI' + '13fh2x' + 'B3x4f2hf7I' * 35 + '40B5I' → 2092 B, CRC over 2088 B (522 u32 words)
  • g1_pub.h switches from the raw-pointer call to crc32_core(msg_) (typed dispatch).
  • The existing crc32_core(uint32_t*, uint32_t) and all Go2 / example callers are untouched.

Out of scope

  • Go2 (unitree_go) LowCmd_ / LowState_ likely have the same issue (same uint8_t mode + float layout in their MotorCmd_), but that fix is unverified on hardware and is left for a follow-up PR.
  • The duplicated crc32_core copies under example/ are unchanged.

Test plan

  • Full SDK builds clean (all G1/H1/H1_2/H2 examples link).
  • Bit-for-bit cross-check vs. unitree_sdk2py.utils.crc.CRC for: empty LowCmd, empty LowState, partial fields, fully-populated 35-motor LowCmd, fully-populated LowState (IMU + 35 motors + wireless_remote + reserve).
  • Hardware-verified for LowCmd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant