Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,65 @@ Mutex-free tf2 alternative for ROS 2. An experimental rewrite of tf2's `BufferCo

tf2's `BufferCore` uses `std::mutex` to protect shared data. This means all concurrent access — including reads — is serialized. tfl is an experimental attempt to remove mutex locks entirely, using SeqLock + wait-free hash map to allow concurrent reads without blocking.

## Benchmark

See [benchmark/README.md](benchmark/README.md).

## Packages

| Package | Description |
|---------|-------------|
| `tfl` | Core library. No ROS dependencies. Mutex-free transform buffer. |
| `tfl_ros` | ROS 2 integration. Subscribes to `/tf` and `/tf_static`, feeds into `tfl::TransformBuffer`. |

## Prerequisites

- Docker

`run.sh` wraps `docker run` with `--user $(id -u):$(id -g)` so that build artifacts are owned by your user, not root. On first run it builds the Docker image automatically.

## Setup

```bash
# Create colcon workspace with symlinks
mkdir -p ws/src
ln -s ../../tfl ws/src/tfl
ln -s ../../tfl_ros ws/src/tfl_ros # optional
```

## Build

```bash
ROS_DISTRO=jazzy ./run.sh bash -c \
"cd benchmark/ws \
&& source /opt/ros/\$ROS_DISTRO/setup.bash \
# tfl only
./run.sh bash -c \
"source /opt/ros/\$ROS_DISTRO/setup.bash \
&& cd ws \
&& colcon build --packages-select tfl"

# tfl + tfl_ros
./run.sh bash -c \
"source /opt/ros/\$ROS_DISTRO/setup.bash \
&& cd ws \
&& colcon build --packages-select tfl tfl_ros"
```

## Example
## Test

```bash
./run.sh bash -c \
"source /opt/ros/\$ROS_DISTRO/setup.bash \
&& cd ws \
&& colcon test --packages-select tfl \
&& colcon test-result --verbose"
```

## Benchmark

```bash
./run.sh bash -c \
"source /opt/ros/\$ROS_DISTRO/setup.bash \
&& cd ws \
&& source install/setup.bash \
&& ./build/tfl/bench_lookup"
```

Coming soon.
For tf2 comparison benchmarks, see [benchmark/README.md](benchmark/README.md).

## Design

Expand Down Expand Up @@ -62,9 +98,8 @@ Writer thread (single) Reader threads (many)

## Requirements

- C++17
- CMake 3.14+
- ROS 2 Jazzy or Rolling (for tfl_ros; tfl itself has no ROS dependency)
- Docker (for building via `run.sh`)
- Or: C++17, CMake 3.14+, ROS 2 Jazzy or Rolling

## License

Expand Down
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fi
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "$REPO_ROOT:$REPO_ROOT" \
-w "$(pwd)" \
-w "$REPO_ROOT" \
-e HOME=/tmp/home \
-e "ROS_DISTRO=${ROS_DISTRO}" \
"$IMAGE_NAME" \
Expand Down
3 changes: 3 additions & 0 deletions tfl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ if(BUILD_TESTING)

ament_add_gtest(test_stress test/test_stress.cpp TIMEOUT 30)
target_link_libraries(test_stress ${PROJECT_NAME})

add_executable(bench_lookup test/bench_lookup.cpp)
target_link_libraries(bench_lookup ${PROJECT_NAME})
endif()

ament_package()
16 changes: 0 additions & 16 deletions tfl/include/tfl/transform_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,6 @@ class TransformBuffer
void clear();

private:
struct TransformAccum
{
TransformData::Quat source_to_top_quat = {0, 0, 0, 1};
TransformData::Vec3 source_to_top_vec = {0, 0, 0};
TransformData::Quat target_to_top_quat = {0, 0, 0, 1};
TransformData::Vec3 target_to_top_vec = {0, 0, 0};
TimeNs time = 0;

void accum_source(const TransformData & st);
void accum_target(const TransformData & st);
TransformData finalize_identity() const;
TransformData finalize_target_parent_of_source() const;
TransformData finalize_source_parent_of_target() const;
TransformData finalize_full_path() const;
};

FrameID register_frame(const std::string & name, bool is_static = false);
FrameID resolve_frame_id(const std::string & name) const;

Expand Down
Loading