Repository navigation
fix: ROSBag finds the end of image data from the message layout, not a guess - #163
Merged
Merged
Conversation
…a guess The Intel RealSense SDK follows every image message in a bag with 4 extra bytes (a float32 depth scale). The reader handled that by assuming 4 trailing bytes on every message of any bag that has a realsense_msgs connection, and only when release="auto". Tested on real bags this had three problems: - ROSBag(path) with the default release="ROS1_NOETIC" read no frames at all from the RealSense recording: SerdeError "ROS1 message size mismatch". Current rosbags raises SerdeError, the code only caught AssertionError. - Intel's own sample bag (single_depth_color_640x480.bag) has realsense_msgs connections but no extra bytes. With release="auto" the reader removed 4 real bytes from every image and silently returned no frames. - The depth scale was discarded. Now sensor_msgs/Image and CompressedImage (ROS 1 and CDR, either byte order) are parsed up to the end of their data array, checking that the array length is height * step. Only those bytes are deserialized and anything after them is the footer. Pixels are unchanged. What to make of the footer is decided by context, because the bytes cannot decide it: about half of all 4-byte patterns are a positive, finite float32. In a bag recognised as RealSense (a realsense_msgs connection), a positive finite float32 is attached to the image as `depth_units` (metres per unit) and 4 zero bytes (a color image) mean no scale. Anything else after an image, such as the same 4 bytes in a bag that is not recognised, another length, or a negative or non-finite value, is ignored with a RuntimeWarning, once per topic. CDR padding (up to 3 zero bytes) is silent. Every other message type must be exactly the length its type says, as a serialization format requires, and is no longer tried with 0, 4 and 8 bytes removed. That guess was unnecessary: all 68,889 non-image messages in the 13 real bags tested decode at their exact length. Verified on every bag in bags/ (14 files, old reader vs new): output is byte-identical for all except the two cases above, which now work; the RealSense bag gives depth_units == 0.001 on its 37 depth frames and no warnings. Adds tests/test_ros_realsense.py: the layout parser and footer decoder, synthetic RealSense-style bags written to a temporary directory by tests/create_ros_fixture.py (ROS 1 and CDR, with and without footers and realsense_msgs), unexpected trailing bytes, exact-length decoding of other messages, and checks against the real bags when they are present. Refs #151. The depth_units=/invalid_is_nan= conversion options are not in this change. The layout-parsing approach follows #154 and the technique for building the synthetic bag follows #155. Co-authored-by: TianHengZhuang <39034691+TianHengZhuang@users.noreply.github.com> Co-authored-by: theluckystrike <51033404+theluckystrike@users.noreply.github.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 22, 2026
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 77 |
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
4 tasks done
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.
Summary
The Intel RealSense SDK follows every image message in a bag with 4 extra bytes (a
float32depth scale). The reader handled that by assuming 4 trailing bytes on every message of any bag with arealsense_msgsconnection, and only whenrelease="auto". Tested on the real bags in a development checkout, this had three problems:ROSBag(path)reads 0 frames (SerdeError: ROS1 message size mismatch);autoworks but discards the footerdepth_units == 0.001on the depth streamsingle_depth_color_640x480.bag(realsense_msgsconnections, no footers)autoreturns 0 frames, silently (it removes 4 real bytes from every image)What changes
sensor_msgs/ImageandCompressedImage(ROS 1 and CDR, either byte order) are parsed to the end of their data array, checkinglength == height * step. Only those bytes are deserialized; anything after them is the footer. Pixels are unchanged.float32). In a bag recognised as RealSense, a positive finite float becomes the image'sdepth_unitsattribute (metres per unit) and four zero bytes (a color image) mean no scale. Anything else after an image (the same 4 bytes in an unrecognised bag, another length, a negative or non-finite value) is ignored with aRuntimeWarning, once per topic. CDR padding is silent.SerdeErroris caught as well asAssertionError(currentrosbagsraisesSerdeError).ROSBag,_image_payload_end,_footer_depth_unitsand_image_depth_units.Related issue
Refs #151. The
depth_units=/invalid_is_nan=conversion options are not in this PR; they will follow separately.Credit
The approach of finding the end of the data from the message layout follows #154 (@TianHengZhuang), and the technique for building a synthetic RealSense-style bag in the tests follows #155 (@theluckystrike). Both are credited as co-authors on the commit. Thank you both.
Verification
tests/test_ros_realsense.py(332 tests): the layout parser, footer decoder, synthetic RealSense-style bags written to a temporary directory bytests/create_ros_fixture.py(ROS 1 / CDR LE / CDR BE, with and without footers andrealsense_msgs), unexpected trailing bytes, exact-length decoding of other messages, and checks against real bags that skip whenbags/is absent. No binary fixtures are committed.pytest tests: 1367 passed, 44 skipped.bags/(14 files): identical pixels on every frame.Checklist
pytest)🤖 Generated with Claude Code