Skip to content

Releases: facontidavide/data_tamer

2.0.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 15:20

First release of the 2.x series, relative to 1.0.4. It breaks source and binary
compatibility: rebuild every binary that links data_tamer, and read docs/MIGRATION.md,
which gives the replacement for each removed API and lists the behaviour changes that
compile without a warning. Readers need the 2.0 parser for files recorded by 2.0; it still
reads 1.x files.

Breaking changes

  • The namespace is DataTamer2 (was DataTamer), the headers are in
    data_tamer_v2/ (were data_tamer/) and the standalone parser is
    data_tamer_v2/data_tamer_parser.hpp (was
    data_tamer_parser/data_tamer_parser.hpp). SerializeMe and DataTamerParser
    keep their names, inside an inline namespace v2.
  • DataSinkBase is replaced by DataSink, whose protected callbacks are
    onSchema(), onSnapshot(const SnapshotRef&) and the optional onStop() and
    onStart() (throw to report a failure), owned by a SinkWorker that runs the
    delivery thread. addChannel(), pushSnapshot(), storeSnapshot(),
    stopThread(), stopAcceptingSnapshots(), processQueuedSnapshots() and
    startAcceptingSnapshots() are gone: use SinkWorker::stop(), drain() and
    start(). To write data_tamer MCAP files from your own data, use
    sinks/mcap_encoding.hpp.
  • Sinks are created with MCAPSink::create(), ROS2PublisherSink::create(),
    DummySink::create() or SinkWorker::create<T>(), which return a
    std::shared_ptr<SinkWorkerOf<T>>: a SinkWorker whose sink() is the T
    (static cast, no dynamic_cast), converting to the std::shared_ptr<SinkWorker>
    that addDataSink() and addDefaultSink() take. worker->as<T>() reaches the
    sink through a plain SinkWorker (std::bad_cast for the wrong type). Passing
    std::make_shared<MCAPSink>(path), as in 1.x, to addDataSink(),
    removeDataSink() or addDefaultSink() fails with a static_assert that names
    MCAPSink::create() and SinkWorker::create<T>().
    LogChannel::addDataSink() takes the worker and returns bool (false if it was
    attached already). MCAPSink::finishQueueAndStop() is removed (worker->stop()),
    restartRecording() no longer resumes a stopped worker, and DummySink has
    accessors (latestSnapshot(), schema(hash), ...) instead of public members.
  • Snapshot has no channel_name (use Schema::channel_name, matched by
    schema_hash), and schema_hash is uint64_t. DataSnapshot is removed.
  • takeSnapshot() returns a SnapshotResult instead of bool (accepted(result)
    replaces the bool).
    getActiveFlags() is removed: isEnabled(id) in the application,
    Snapshot::active_mask in a sink.
  • LogChannel::writeMutex() and the Mutex alias are removed: another thread writes
    registered variables inside scopedWrite().
  • LoggedValue: scalars are atomic and use set() and get() only. Structs and
    vectors keep getMutablePtr() and getConstPtr(), whose guards are not movable and
    have no operator bool and no mutex(). getLockedPtr() and the auto_enable
    parameter of set() are removed. A LoggedValue can't be moved or
    default-constructed.
  • RegistrationID is opaque: no first_index, fields_count or operator+=.
  • CustomSerializerT(std::string) is explicit, CustomTypeName<T>::get() is not
    constexpr, Schema::custom_types and custom_schemas are std::map (were
    std::unordered_map), and long double is a compile error. Removed:
    getPointerType(), SerializeMe::enable_if_same_t and the library's
    AddFieldToHash(), replaced by SchemaTextHash() and ComputeSchemaHash() (the
    parser keeps its own, for version 4 texts).
  • Parser: ParseSnapshot() loses its unused callback_custom parameter and is
    [[nodiscard]]; ParseSnapshotRecursive moves to DataTamerParser::detail and
    NullCustomCallback is removed; SnapshotView::schema_hash is uint64_t;
    BuilSchemaFromText() is a deprecated alias of BuildSchemaFromText(). The header
    needs a little-endian host and no longer includes <iostream>.
  • sinks/ros2_publisher_sink.hpp no longer includes the data_tamer_msgs headers.

Behaviour changes

  • MCAPSink continues in a new numbered file at every reset (600 s by default) instead
    of truncating its file, so disk use is unbounded; setCreateNewFileOnReset(false)
    truncates as before. Rollover files are named run_1.mcap (1.x: run.mcap_1) and
    skip names that exist; the path passed to create() is still overwritten.
  • SinkWorker::stop() delivers what is queued, then finishes the sink: MCAPSink
    closes its file, and start() continues in the next numbered file. Destroying a
    running worker stops it.
  • A channel's snapshot pool bounds the memory of its sinks: by default as many slots as
    fit in 8 MiB, from 64 to 1024, per channel. A sink that falls behind loses snapshots
    (pool_exhausted) instead of growing a queue.
  • ROS2PublisherSink: the data topic is reliable KeepLast(100) (was KeepAll;
    ROS2PublisherOptions::data_qos), and the schemas topic is transient-local
    KeepLast(1), published by startLogging().
  • LoggedValue::set() never re-enables a disabled value. set() and get() of a
    struct or vector lock the channel's write mutex, so they wait for a snapshot in
    progress.
  • An id kept across unregister() and a new registration of the same name is stale:
    setEnabled() and unregister() throw std::invalid_argument (1.x acted on the
    new registration).
  • A snapshot taken by a thread that holds the write mutex (scopedWrite(), a
    LoggedValue guard) returns blocked; in 1.x it deadlocked.
  • From a sink callback, a control call that would wait for that callback's own worker
    throws std::logic_error and changes nothing instead of deadlocking (see DataSink
    in data_sink.hpp).
  • Value names, custom type names and field names must be non-empty and free of whitespace
    and control characters (1.x refused only spaces); a channel name can't be empty or hold
    a control character. Two C++ types with one custom type name in a channel make
    registerValue() throw.
  • A channel holds at most 8 sinks, and a registry at most 8 default sinks.
    addDefaultSink() also attaches the sink to the channels that exist already.
  • MCAP messages carry a sequence number, 1, 2, 3, ... per channel and file (was always 1).
    The MCAP sinks don't write a snapshot with a negative timestamp; they count it in
    errors().
  • Wire format: the schema text is version 5 and its hash is FNV-1a 64 of the text, the
    same on every platform. A std::string is written as char[], a uint32 count
    and the characters. 1.x readers reject 2.0 files: use PlotJuggler 4 or a 2.0 parser.
  • The parsers reject a schema text without a ### version: line (releases before
    0.7.0). ParseSnapshot() returns false when bytes are left after the last field, and
    throws on malformed data.

New

  • LogChannel::startLogging() freezes the schema, allocates the pool and announces the
    schema; the first takeSnapshot() or tryTakeSnapshot() with a sink attached
    calls it. tryTakeSnapshot(), for real-time threads, never blocks or allocates once
    logging started, also when data_tamer is loaded with dlopen(); the call that starts
    logging is not real-time (RealtimeSanitizer reports it), so call startLogging()
    before the loop. Without a sink it returns no_sinks, in real time; if starting
    throws, start_failed, and the next call retries. Several threads may take snapshots
    of one channel.
  • accepted(SnapshotResult), constexpr and real-time safe: true for ok and
    partial, what stats().accepted counts.
  • tryTakeSnapshot() is noexcept: a serializer that throws ends it with
    SnapshotResult::serialize_failed, counted by serializeFailures();
    takeSnapshot() lets the exception through, as in 1.x. The library catches it, so
    serializers compiled into binaries built against earlier headers are covered too.
  • LogChannel::scopedWrite() groups writes from another thread into one snapshot.
    registerValue() accepts a const std::atomic<T>*.
  • setEnabled() is lock-free; new trySetEnabled() (noexcept) and
    isEnabled(id).
  • setPoolCapacity() (a count, or a stall tolerance and a period),
    setPayloadCapacity() and ChannelsRegistry::setChannelDefaults().
  • LogChannel::stats() and SinkWorker::stats(): snapshot attempts and accepted
    snapshots, pool, oversize, serialization-failure and lock counters, refusals per sink,
    deliveries, errors and queue high water.
  • MCAPRingSink, a flight recorder: it keeps the last window of every channel in
    RAM and writes an MCAP file on requestDump(), which is real-time safe.
  • ROS2PublisherSink takes ROS2PublisherOptions: QoS, aggregation into
    data_tamer_msgs/SnapshotBatch (new message) and the schema format.
  • A YAML rendering of the schema (wire format section 2.1, also version 5): ToYaml(),
    RenderSchema(), SchemaFormat::Yaml.
  • DataSink::onStop() and onStart(), SinkWorker::Delivery::Manual (no thread:
    the application calls drain()).
  • ChannelsRegistry::stopAll() and shutdown() (stopAll() then clear(), for
    the end of main(): every sink is finished and no channel is left borrowing your
    variables).
  • TypeDefinitionTrait<T> describes a type without reopening its namespace (Eigen,
    ...).
  • Real-time checks with Clang 20 or later: the real-time API is declared
    [[clang::nonblocking]] (DATA_TAMER_NONBLOCKING), so in a function marked
    [[clang::nonblocking]] -Wfunction-effects rejects a call to takeSnapshot(),
    a registration or a non-scalar LoggedValue::set(), and RealtimeSanitizer
    (-fsanitize=realtime) reports every allocation, lock or system call at run time,
    in data_tamer and in custom serializers. On Linux (ELF) data_tamer declares to RTSan
    the futex calls the real-time contract allows. A new rtsan preset and CI job.
  • New headers: names.hpp (JoinNames() and `IsCanonicalName...
Read more

1.0.3

Choose a tag to compare

@henrygerardmoore henrygerardmoore released this 23 May 19:26
ae41fff

What's Changed

Full Changelog: 1.0.2...1.0.3

1.0.2

Choose a tag to compare

@henrygerardmoore henrygerardmoore released this 12 May 19:54
1085e00

What's Changed

Full Changelog: 1.0.1...1.0.2

1.0.1

Choose a tag to compare

@facontidavide facontidavide released this 03 Mar 11:53
  • force the size of BasicType ot be 1 byte (#47 <https://github.com/PickNikRobotics/data_tamer/issues/47>_)
    This fix the issue when the log is generated on two different computers
    using different compilers (example Linux / QNX)
  • add file reset capabilities (#37 <https://github.com/PickNikRobotics/data_tamer/issues/37>_)
  • Enable users to build without ROS (#36 <https://github.com/PickNikRobotics/data_tamer/issues/36>_)
    • make building with ROS an option
    • clarify warnings, allow for default-building without ROS
    • switch name of ros build flag
    • add build ros argument for examples
    • fix incorrect message
  • Merge pull request #32 <https://github.com/PickNikRobotics/data_tamer/issues/32>_ from PickNikRobotics/default_increment_filename
    Allow endless recording
  • allow for unlimited recording
  • use a new mutex wrapper API (#27 <https://github.com/PickNikRobotics/data_tamer/issues/27>_)e non-deprecated function
  • Locked ptr test, documentation, and example (#24 <https://github.com/PickNikRobotics/data_tamer/issues/24>_)
    • add locked ptr usage to example
    • update comment relating to locked ptr
    • remove unused headers
    • add test for locked ptr and non-blocking method
    • remove unsafe lockedPtr get function
  • Merge pull request #23 <https://github.com/PickNikRobotics/data_tamer/issues/23>_ from torsoelectronics/main
  • Contributors: Daniel Mouritzen, Davide Faconti, Henry Moore

0.9.3: bug fixes, mostly.

Choose a tag to compare

@facontidavide facontidavide released this 01 Feb 18:13

No new features

0.9.0: First official beta

Choose a tag to compare

@facontidavide facontidavide released this 14 Dec 21:38

Data Tamer is ready to be tested more broadly. Try it and let us now

New type system for custom types and new schema

Choose a tag to compare

@facontidavide facontidavide released this 28 Nov 19:23

Complete refactoring on the custom types.

0.6.0: Back compatibility and ROS2 Sink finalized

Choose a tag to compare

@facontidavide facontidavide released this 23 Nov 13:51
0.6.0

Welcome Data Tamer (alpha)

Choose a tag to compare

@facontidavide facontidavide released this 22 Nov 13:05

This is the first alpha release of the library.

It is usable, but the API is not stable yet.