|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler | |
| data_tamer_tools |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler | |
| data_tamer_tools |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler | |
| data_tamer_tools |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |
Launch files
Messages
Services
Plugins
Recent questions tagged data_tamer_cpp at Robotics Stack Exchange
|
data_tamer_cpp package from data_tamer repodata_tamer_cpp data_tamer_msgs |
ROS Distro
|
Package Summary
| Version | 2.0.0 |
| License | MIT |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Description | C++ library for Fearless Timeseries Logging |
| Checkout URI | https://github.com/PickNikRobotics/data_tamer.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-10-09 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Davide Faconti
- Henry Moore
- Nathan Brooks
Authors
- Davide Faconti
Changelog for package data_tamer
Unreleased
-
Fixed, deadlocks:
unregister(),removeDataSink()or aLoggedValuedestructor insidescopedWrite()while a snapshot waited; a const query insidescopedWrite()while another thread ran one of those, orstartLogging();startLogging()insidescopedWrite(). The snapshot path takes the write mutex before its epoch, andstartLogging()before the control mutex. -
Behaviour change: a snapshot taken by a thread that holds the
channel's transaction or a
LoggedValueguard returnsblocked(it hung). -
New: several threads may take snapshots of one channel; they
take turns on the write mutex.
blockednow takes precedence overpool_exhausted. -
Fixed: a consumer built with
-fvisibility=hiddenagainst a shared libdata_tamer hung inLoggedValue::set()insidescopedWrite();ChannelSharedStatehas default visibility. -
Behaviour change:
SinkWorker::stop(),start()anddrain()throwstd::logic_errorfrom a callback of their own sink (they deadlocked, orstop()closed the worker silently). Concurrentstop()andstart(), twostopAll()included, are serialized (they hung). A callback that releases the last reference to its own worker no longer callsstd::terminate. -
Fixed: a sink attached during a failing
startLogging()could miss the final schema, and a concurrentaddDataSink()of one worker announced it twice. -
Real-time: no
notify_all()per snapshot or refused push unless a thread waits; each one could be a futex call. -
Behaviour change: names must be non-empty and free of whitespace
and control characters (only the space was refused);
IsCanonicalName()agrees. A ninth default sink throws inaddDefaultSink()(it made every latergetChannel()throw). -
Behaviour change: custom type names, their field names, the
typeName()of aregisterCustomValue()serializer and channel names are checked too: a line break in any of them split the schema text, and a space in a type or field name broke its field line. Type and field names follow the value name rules, and the registration throwsstd::runtime_error. A channel name can contain spaces, butLogChannel::create()andgetChannel()throw for an empty one or one with a control character. -
Fixed: a registration that throws leaves the channel unchanged
(custom types, an allocation failure,
createLoggedValue()). Two C++ types that return one custom type name in a channel makeregisterValue()throw (the second used the first one's serializer and read past its object).ToStr(Schema)rethrows allocation failures. -
Fixed:
long long,unsigned long long,wchar_t,char16_t,char32_tand enums over them are recorded by size and signedness; they were recorded asother, which no decoder reads.long doubleis a compile error. A class template with two or more type parameters can have aTypeDefinition. -
Fixed: a vector of structs was sized with padding, so
tryTakeSnapshot()could returnoversizefor a payload that fit.ValuePtrchecks the room before writing a number and writes little-endian on any host; a custom type without a serializer throwsstd::invalid_argument. -
Fixed, wire: a
std::string, registered or inside a custom type, is written aschar[](auint32count and the characters), as its schema says. It carried a 16-bit length that no decoder could read, and a string over 65535 bytes made the snapshot throw. -
Fixed:
MCAPSinkreset without rollover andrestartRecording()of the file in use wrote the old footer into the new file; the old writer is now closed first, and a failed reopen of that file stops the sink. A rollover that cannot open its next file is counted once and retried after another reset time. -
Fixed:
MCAPRingSink::flushPendingDump()andstop()on an untriggered request use the newest timestamp of the current run, so a simulation reset no longer dumps the previous run.dumps_writtenanddumps_failedcount a dump before its callback. -
Fixed:
MCAPRingSinkstarts a new run only when a channel's clock steps back by more thanwindow. Snapshots of one channel taken by several threads can arrive slightly out of order, and each step back started a run, so a flush right after ended its dump before the newest snapshot. -
Behaviour change: MCAP sinks reject a negative snapshot
timestamp (counted in
errors(), not written), andmcap_encoding::WriteMessage()throws for one. -
Parser and Python decoder: the work of a decode is bounded by
the payload (a zero-size element type looped for minutes); a bool is
true for any non-zero byte; empty schema text is rejected;
### key:valueheaders are read; version and hash are strict unsigned decimals; a separator is a whole line of at least 30=;ENCODING:sections are opaque types and must followMSG:; upper-case legacy names are read only without a### version:line. NewSplitMcapMessage()andsplit_mcap_message(), used bymcap_reader. -
Breaking, parser:
ParseSnapshot()loses its unusedcallback_customparameter;SizeOf,kMaxSchemaDepthandParseSnapshotRecursivemove toDataTamerParser::detailandNullCustomCallbackis removed; the header needs a little endian host and no longer includes<iostream>. -
SerializeMe: bounds checks for byte vectors and 1-byte arrays,
exact
BufferSize()for arrays and padded structs, bool decoding, a container of 2\^32 elements or more throws, an ADLTypeDefinition()may returnconst char*orstd::string,Span<const T>fromstd::array, and the big endian path compiles for enums andstd::byte. -
API:
[[nodiscard]]ontrySetEnabled(),
File truncated at 100 lines see the full file
Package Dependencies
| Deps | Name |
|---|---|
| ament_cmake | |
| rclcpp | |
| rclcpp_lifecycle | |
| mcap_vendor | |
| data_tamer_msgs | |
| ament_cmake_gtest | |
| gtest_vendor |
System Dependencies
| Name |
|---|
| lz4 |
| libzstd-dev |
Dependant Packages
| Name | Deps |
|---|---|
| plotjuggler |