chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:05:14 +08:00
commit 2a547be7fe
7904 changed files with 1000926 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
add_subdirectory(clock)
add_subdirectory(custom_collection_adapter)
add_subdirectory(dna)
add_subdirectory(external_importer)
add_subdirectory(incremental_logging)
add_subdirectory(log_file)
add_subdirectory(minimal)
add_subdirectory(shared_recording)
add_subdirectory(spawn_viewer)
add_subdirectory(stdio)
add_custom_target(examples)
add_dependencies(examples example_clock)
add_dependencies(examples example_custom_collection_adapter)
add_dependencies(examples example_dna)
add_dependencies(examples example_incremental_logging)
add_dependencies(examples example_log_file)
add_dependencies(examples example_minimal)
add_dependencies(examples example_shared_recording)
add_dependencies(examples example_spawn_viewer)
add_dependencies(examples example_stdio)
add_dependencies(examples rerun-importer-cpp-file)
+14
View File
@@ -0,0 +1,14 @@
# Rerun C++ examples
The simplest example is [`minimal`](minimal/main.cpp). You may want to start there
using the accompanying [`C++ Quick Start`](https://www.rerun.io/docs/getting-started/data-in/cpp) guide.
## Build all examples
The CMake target `examples` is a convenient alias for building all CMake examples in one go.
You can use `pixi run -e cpp cpp-build-examples` to invoke it within the repository's Pixi environment.
After that, you can run individual examples from `./build/examples/cpp/` (e.g. `./build/examples/cpp/dna/example_dna`).
## Contributions welcome
Feel free to open a PR to add a new example!
See [`CONTRIBUTING.md`](../../CONTRIBUTING.md) for details on how to contribute.
+24
View File
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_clock main.cpp)
rerun_strict_warning_settings(example_clock)
else()
project(example_clock LANGUAGES CXX)
add_executable(example_clock main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
# Link against rerun_sdk.
target_link_libraries(example_clock PRIVATE rerun_sdk)
+24
View File
@@ -0,0 +1,24 @@
<!--[metadata]
title = "Clock"
thumbnail = "https://static.rerun.io/clock/8c49e25f5cac4d6a1d7d0490b14cf6881bdb707b/480w.png"
thumbnail_dimensions = [480, 480]
-->
<picture>
<source media="(max-width: 480px)" srcset="https://static.rerun.io/clock/05e69dc20c9a28005f1ffe7f0f2ac9eeaa95ba3b/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/clock/05e69dc20c9a28005f1ffe7f0f2ac9eeaa95ba3b/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/clock/05e69dc20c9a28005f1ffe7f0f2ac9eeaa95ba3b/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/clock/05e69dc20c9a28005f1ffe7f0f2ac9eeaa95ba3b/1200w.png">
<img src="https://static.rerun.io/clock/05e69dc20c9a28005f1ffe7f0f2ac9eeaa95ba3b/full.png" alt="Clock example screenshot">
</picture>
An example visualizing an analog clock with hour, minute and seconds hands using Rerun Arrow3D primitives.
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_clock
./examples/cpp/clock/example_clock
```
+56
View File
@@ -0,0 +1,56 @@
#include <rerun.hpp>
#include <algorithm> // std::max
#include <cmath>
#include <string>
using namespace std::chrono;
constexpr float TAU = 6.28318530717958647692528676655900577f;
void log_hand(
const rerun::RecordingStream& rec, const char* name, seconds step, float angle, float length,
float width, uint8_t blue
) {
const auto tip = rerun::Vec3D{length * sinf(angle * TAU), length * cosf(angle * TAU), 0.0f};
const auto c = static_cast<uint8_t>(angle * 255.0f);
const auto color =
rerun::Color{static_cast<uint8_t>(255 - c), c, blue, std::max<uint8_t>(128, blue)};
rec.set_time_duration("sim_time", step);
rec.log(
std::string("world/") + name + "_pt",
rerun::Points3D(rerun::Position3D(tip)).with_colors(color)
);
rec.log(
std::string("world/") + name + "hand",
rerun::Arrows3D::from_vectors(rerun::Vector3D(tip))
.with_origins({{0.0f, 0.0f, 0.0f}})
.with_colors(color)
.with_radii({width * 0.5f})
);
}
int main() {
const float LENGTH_S = 20.0f;
const float LENGTH_M = 10.0f;
const float LENGTH_H = 4.0f;
const float WIDTH_S = 0.25f;
const float WIDTH_M = 0.4f;
const float WIDTH_H = 0.6f;
const int num_steps = 10000;
const auto rec = rerun::RecordingStream("rerun_example_clock");
rec.spawn().exit_on_failure();
rec.log_static("world", rerun::ViewCoordinates::RIGHT_HAND_Y_UP);
rec.log_static("world/frame", rerun::Boxes3D::from_half_sizes({{LENGTH_S, LENGTH_S, 1.0f}}));
for (int step = 0; step < num_steps; step++) {
log_hand(rec, "seconds", seconds(step), (step % 60) / 60.0f, LENGTH_S, WIDTH_S, 0);
log_hand(rec, "minutes", seconds(step), (step % 3600) / 3600.0f, LENGTH_M, WIDTH_M, 128);
log_hand(rec, "hours", seconds(step), (step % 43200) / 43200.0f, LENGTH_H, WIDTH_H, 255);
}
}
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_custom_collection_adapter main.cpp)
rerun_strict_warning_settings(example_custom_collection_adapter)
else()
project(example_custom_collection_adapter LANGUAGES CXX)
add_executable(example_custom_collection_adapter main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
# Link against rerun_sdk.
target_link_libraries(example_custom_collection_adapter PRIVATE rerun_sdk)
@@ -0,0 +1,29 @@
# Custom collection adapter
Especially when dealing with large amounts of data, it can be both slow and inconvenient to convert
your data into the components & datatypes provided by the Rerun SDK in order to log it.
This example demonstrates how to solve this using [`rerun::ComponentAdapter`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1CollectionAdapter.html) for your own types:
Whenever you have data that is continuous in memory and binary compatible with an existing Rerun component,
you can adapt it to map to the respective Rerun component.
For non-temporary objects that live until [`rerun::RecordingStream::log`](https://ref.rerun.io/docs/cpp/stable/classrerun_1_1RecordingStream.html#af7a14a7e2c3029ef1679ff9fd680129d) returns,
it is typically safe to do so with a zero-copy "borrow".
This means that in those cases [`rerun::Collection`](https://ref.rerun.io/docs/cpp/stable/classrerun_1_1Collection.html) will merely store a pointer and a length to your data.
While collection adapters are primarily used with components, they are also useful for all other usages of
Rerun's collection type. E.g. the backing buffer of [`rerun::TensorData`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1TensorBuffer.html)
is also a [`rerun::Collection`](https://ref.rerun.io/docs/cpp/stable/classrerun_1_1Collection.html)
allowing you to ingest large amounts of data without a copy and the convenience custom adapters can provide.
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_custom_collection_adapter
./examples/cpp/minimal/example_custom_collection_adapter
```
---
* 🚧 TODO(#4257): In the future, adapters will be able to provide simple data transformations like strides to be done as a borrow.
* 🚧 TODO(#3977): We plan to provide adapters for common types from Eigen and OpenCV.
@@ -0,0 +1,61 @@
#include <rerun.hpp>
// A very simple custom container type.
template <typename T>
struct MyContainer {
T* data;
size_t size;
MyContainer(size_t size_) : data(new T[size_]), size(size_) {}
// For demonstration purposes: This container can't be copied.
MyContainer(const MyContainer&) = delete;
~MyContainer() {
delete[] data;
}
};
// A custom vector type.
struct MyVec3 {
float x, y, z;
};
/// Adapts `MyContainer<MyVec3>` to a `Collection<Position3D>`.
///
/// With this in place, `Collection<Position3D>` can be constructed from a `MyContainer<MyVec3>`!
template <>
struct rerun::CollectionAdapter<rerun::Position3D, MyContainer<MyVec3>> {
// Creating a Collection from a non-temporary is done by casting & borrowing binary compatible data.
Collection<rerun::Position3D> operator()(const MyContainer<MyVec3>& container) {
return Collection<rerun::Position3D>::borrow(container.data, container.size);
}
// For temporaries we have to do a copy since the pointer doesn't live long enough.
// If you don't implement this, the other overload may be used for temporaries and cause
// undefined behavior.
Collection<rerun::Position3D> operator()(MyContainer<MyVec3>&& container) {
std::vector<rerun::Position3D> components(container.size);
for (size_t i = 0; i < container.size; ++i) {
components[i] =
rerun::Position3D(container.data[i].x, container.data[i].y, container.data[i].z);
}
return Collection<rerun::Position3D>::take_ownership(std::move(components));
}
};
int main() {
// Create a new `RecordingStream` which sends data over gRPC to the viewer process.
const auto rec = rerun::RecordingStream("rerun_example_custom_component_adapter");
rec.spawn().exit_on_failure();
// Construct some data in a custom format.
MyContainer<MyVec3> points(3);
points.data[0] = MyVec3{0.0f, 0.0f, 0.0f};
points.data[1] = MyVec3{1.0f, 0.0f, 0.0f};
points.data[2] = MyVec3{0.0f, 1.0f, 0.0f};
// Log the "my_points" entity with our data, using the `Points3D` archetype.
// Of course you can mix and match built-in types and custom types on the same archetype.
rec.log("my_points", rerun::Points3D(points).with_labels({"a", "b", "c"}));
}
+24
View File
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_dna main.cpp)
rerun_strict_warning_settings(example_dna)
else()
project(example_dna LANGUAGES CXX)
add_executable(example_dna main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
# Link against rerun_sdk.
target_link_libraries(example_dna PRIVATE rerun_sdk)
+24
View File
@@ -0,0 +1,24 @@
<!--[metadata]
title = "Helix"
tags = ["3D", "API example"]
thumbnail = "https://static.rerun.io/dna/40d9744af3f0e21d3b174054f0a935662a574ce0/480w.png"
thumbnail_dimensions = [480, 480]
channel = "main"
-->
Simple example of logging point and line primitives to draw a 3D helix.
<picture>
<source media="(max-width: 480px)" srcset="https://static.rerun.io/helix/f4c375546fa9d24f7cd3a1a715ebf75b2978817a/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/helix/f4c375546fa9d24f7cd3a1a715ebf75b2978817a/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/helix/f4c375546fa9d24f7cd3a1a715ebf75b2978817a/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/helix/f4c375546fa9d24f7cd3a1a715ebf75b2978817a/1200w.png">
<img src="https://static.rerun.io/helix/f4c375546fa9d24f7cd3a1a715ebf75b2978817a/full.png" alt="">
</picture>
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_dna
./examples/cpp/dna/example_dna
```
+81
View File
@@ -0,0 +1,81 @@
#include <rerun.hpp>
#include <rerun/demo_utils.hpp>
#include <algorithm> // std::generate
#include <random>
#include <vector>
using namespace rerun::demo;
using namespace std::chrono_literals;
static constexpr size_t NUM_POINTS = 100;
int main() {
const auto rec = rerun::RecordingStream("rerun_example_dna_abacus");
rec.spawn().exit_on_failure();
std::vector<rerun::Position3D> points1, points2;
std::vector<rerun::Color> colors1, colors2;
color_spiral(NUM_POINTS, 2.0f, 0.02f, 0.0f, 0.1f, points1, colors1);
color_spiral(NUM_POINTS, 2.0f, 0.02f, TAU * 0.5f, 0.1f, points2, colors2);
rec.set_time_duration("stable_time", 0s);
rec.log_static(
"dna/structure/left",
rerun::Points3D(points1).with_colors(colors1).with_radii({0.08f})
);
rec.log_static(
"dna/structure/right",
rerun::Points3D(points2).with_colors(colors2).with_radii({0.08f})
);
std::vector<rerun::LineStrip3D> lines;
for (size_t i = 0; i < points1.size(); ++i) {
lines.emplace_back(rerun::LineStrip3D({points1[i].xyz, points2[i].xyz}));
}
rec.log_static(
"dna/structure/scaffolding",
rerun::LineStrips3D(lines).with_colors(rerun::Color(128, 128, 128))
);
std::default_random_engine gen;
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
std::vector<float> offsets(NUM_POINTS);
std::generate(offsets.begin(), offsets.end(), [&] { return dist(gen); });
std::vector<rerun::Position3D> beads_positions(lines.size());
std::vector<rerun::Color> beads_colors(lines.size());
for (int t = 0; t < 400; t++) {
auto time = std::chrono::duration<float>(t) * 0.01f;
rec.set_time_duration("stable_time", time);
for (size_t i = 0; i < lines.size(); ++i) {
float time_offset = time.count() + offsets[i];
auto c = static_cast<uint8_t>(bounce_lerp(80.0f, 230.0f, time_offset * 2.0f));
beads_positions[i] = rerun::Position3D(
bounce_lerp(lines[i].points[0].x(), lines[i].points[1].x(), time_offset),
bounce_lerp(lines[i].points[0].y(), lines[i].points[1].y(), time_offset),
bounce_lerp(lines[i].points[0].z(), lines[i].points[1].z(), time_offset)
);
beads_colors[i] = rerun::Color(c, c, c);
}
rec.log(
"dna/structure/scaffolding/beads",
rerun::Points3D(beads_positions).with_colors(beads_colors).with_radii({0.06f})
);
rec.log(
"dna/structure",
rerun::archetypes::Transform3D(rerun::RotationAxisAngle(
{0.0f, 0.0f, 1.0f},
rerun::Angle::radians(time.count() / 4.0f * TAU)
))
);
}
}
+95
View File
@@ -0,0 +1,95 @@
<!--[metadata]
title = "Eigen and OpenCV C++ integration"
source = "https://github.com/rerun-io/cpp-example-opencv-eigen"
tags = ["2D", "3D", "C++", "Eigen", "OpenCV"]
thumbnail = "https://static.rerun.io/eigen-and-opencv-c-integration/5d271725bb9215b55f53767c9dc0db980c73dade/480w.png"
thumbnail_dimensions = [480, 480]
-->
<picture>
<img src="https://static.rerun.io/cpp-example-opencv-eigen/2fc6355fd87fbb4d07cda384ee8805edb68b5e01/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/cpp-example-opencv-eigen/2fc6355fd87fbb4d07cda384ee8805edb68b5e01/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/cpp-example-opencv-eigen/2fc6355fd87fbb4d07cda384ee8805edb68b5e01/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/cpp-example-opencv-eigen/2fc6355fd87fbb4d07cda384ee8805edb68b5e01/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/cpp-example-opencv-eigen/2fc6355fd87fbb4d07cda384ee8805edb68b5e01/1200w.png">
</picture>
This is a minimal CMake project that shows how to use Rerun in your code in conjunction with [Eigen](https://gitlab.com/libeigen/eigen) and [OpenCV](https://opencv.org/).
# Used Rerun types
[`Image`](https://www.rerun.io/docs/reference/types/archetypes/image), [`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d), [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole), [`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d)
# Background
This C++ example demonstrates the integration of the Rerun with Eigen and OpenCV libraries.
Eigen handles 3D point calculations and camera orientations, while OpenCV assists with image processing tasks like reading and converting images.
# Logging and visualizing with Rerun
The visualizations in this example were created with the following Rerun code:
## 3D points
The positions of 3D points are logged to the "world/points_from_vector" and "world/points_from_matrix" entities using the [`Points3D`](https://www.rerun.io/docs/reference/types/archetypes/points3d) archetype.
```cpp
rec.log("world/points_from_vector", rerun::Points3D(points3d_vector));
```
```cpp
rec.log("world/points_from_matrix", rerun::Points3D(points3d_matrix));
```
## Pinhole camera
A pinhole camera is logged to "world/camera" using the [`Pinhole`](https://www.rerun.io/docs/reference/types/archetypes/pinhole) archetype.
Additionally, the 3D transformation of the camera, including its position and orientation, is logged using the [`Transform3D`](https://www.rerun.io/docs/reference/types/archetypes/transform3d) archetype.
```cpp
rec.log(
"world/camera",
rerun::Pinhole::from_focal_length_and_resolution({500.0, 500.0}, {640.0, 480.0})
);
```
```cpp
rec.log(
"world/camera",
rerun::Transform3D(
rerun::Vec3D(camera_position.data()),
rerun::Mat3x3(camera_orientation.data())
)
);
```
## Images
Images are logged using the [`Image`](https://www.rerun.io/docs/reference/types/archetypes/image) archetype. Two methods are demonstrated: logging images with a tensor buffer and logging images by passing a pointer to the image data.
```cpp
// Log image to rerun by borrowing binary data into a `Collection` from a pointer.
rec.log(
"image0",
rerun::Image(
rerun::borrow(img.data, img.total() * img.elemSize()),
rerun::WidthHeight(
static_cast<uint32_t>(img.cols),
static_cast<uint32_t>(img.rows)
),
rerun::ColorModel::BGR
)
);
// Or by passing a pointer to the image data.
rec.log(
"image1",
rerun::Image(
reinterpret_cast<const uint8_t*>(img.data),
rerun::WidthHeight(
static_cast<uint32_t>(img.cols),
static_cast<uint32_t>(img.rows)
),
rerun::ColorModel::BGR
)
);
```
# Run the code
You can find the build instructions here: [C++ Example with OpenCV and Eigen](https://github.com/rerun-io/cpp-example-opencv-eigen/blob/main/README.md)
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(rerun-importer-cpp-file main.cpp)
rerun_strict_warning_settings(rerun-importer-cpp-file)
else()
project(rerun-importer-cpp-file LANGUAGES CXX)
add_executable(rerun-importer-cpp-file main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)
if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
endif()
# Link against rerun_sdk.
target_link_libraries(rerun-importer-cpp-file PRIVATE rerun_sdk)
+24
View File
@@ -0,0 +1,24 @@
---
title: External importer example
python: https://github.com/rerun-io/rerun/tree/latest/examples/python/external_importer/rerun-importer-python-file.py
rust: https://github.com/rerun-io/rerun/tree/latest/examples/rust/external_importer/src/main.rs
cpp: https://github.com/rerun-io/rerun/tree/latest/examples/cpp/external_importer/main.cpp
thumbnail: https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/480w.png
---
<picture>
<img src="https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/external_data_loader_cpp/83cd3c2a322911cf597cf74aeda01c8fe83e275f/1200w.png">
</picture>
This is an example executable importer plugin for the Rerun Viewer.
It will log C++ source code files as markdown documents.
To try it out, compile it and place it in your $PATH, then open a C++ source file with Rerun (`rerun file.cpp`).
Consider using the [`send_columns`](https://ref.rerun.io/docs/cpp/stable/classrerun_1_1RecordingStream.html#ad17571d51185ce2fc2fc2f5c3070ad65) API for importers that ingest time series data from a file.
This can be much more efficient that the stateful `log` API as it allows bundling
component data over time into a single call consuming a continuous block of memory.
+137
View File
@@ -0,0 +1,137 @@
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <rerun.hpp>
#include <rerun/third_party/cxxopts.hpp>
#include <string_view>
void set_time_from_args(const rerun::RecordingStream& rec, cxxopts::ParseResult& args) {
if (args.count("time_sequence")) {
const auto sequences = args["time_sequence"].as<std::vector<std::string>>();
for (const auto& sequence_str : sequences) {
auto pos = sequence_str.find('=');
if (pos != std::string::npos) {
auto timeline_name = sequence_str.substr(0, pos);
int64_t sequence = std::stol(sequence_str.substr(pos + 1));
rec.set_time_sequence(timeline_name, sequence);
}
}
}
if (args.count("time_duration_nanos")) {
const auto times = args["time_duration_nanos"].as<std::vector<std::string>>();
for (const auto& time_str : times) {
auto pos = time_str.find('=');
if (pos != std::string::npos) {
auto timeline_name = time_str.substr(0, pos);
int64_t time = std::stol(time_str.substr(pos + 1));
rec.set_time_duration_nanos(timeline_name, time);
}
}
}
if (args.count("time_timestamp_nanos")) {
const auto times = args["time_timestamp_nanos"].as<std::vector<std::string>>();
for (const auto& time_str : times) {
auto pos = time_str.find('=');
if (pos != std::string::npos) {
auto timeline_name = time_str.substr(0, pos);
int64_t time = std::stol(time_str.substr(pos + 1));
rec.set_time_timestamp_nanos_since_epoch(timeline_name, time);
}
}
}
}
int main(int argc, char* argv[]) {
// The Rerun Viewer will always pass these two pieces of information:
// 1. The path to be loaded, as a positional arg.
// 2. A shared recording ID, via the `--recording-id` flag.
//
// It is up to you whether you make use of that shared recording ID or not.
// If you use it, the data will end up in the same recording as all other plugins interested in
// that file, otherwise you can just create a dedicated recording for it. Or both.
//
// Check out `re_importer::ImporterSettings` documentation for an exhaustive listing of
// the available CLI parameters.
cxxopts::Options options(
"rerun-importer-cpp-file",
R"(
This is an example executable importer plugin for the Rerun Viewer.
Any executable on your `$PATH` with a name that starts with `rerun-importer-` will be treated as an
external importer.
This particular one will log C++ source code files as markdown documents, and return a
special exit code to indicate that it doesn't support anything else.
To try it out, compile it and place it in your $PATH as `rerun-importer-cpp-file`, then open a C++ source
file with Rerun (`rerun file.cpp`).
)"
);
// clang-format off
options.add_options()
("h,help", "Print usage")
("filepath", "The filepath to be loaded and logged", cxxopts::value<std::string>())
("application-id", "Optional recommended ID for the application", cxxopts::value<std::string>())
("recording-id", "Optional recommended ID for the recording", cxxopts::value<std::string>())
("entity-path-prefix", "Optional prefix for all entity paths", cxxopts::value<std::string>())
("static", "Optionally mark data to be logged as static", cxxopts::value<bool>()->default_value("false"))
("time_sequence", "Optional sequences to log at (e.g. `--time_sequence sim_frame=42`) (repeatable)", cxxopts::value<std::vector<std::string>>())
("time_duration_nanos", "Optional durations (nanoseconds) to log at (e.g. `--time_duration_nanos sim_time=123`) (repeatable)", cxxopts::value<std::vector<std::string>>())
("time_timestamp_nanos", "Optional timestamps (nanos since epoch) to log at (e.g. `--time_timestamp_nanos sim_time=1709203426123456789`) (repeatable)", cxxopts::value<std::vector<std::string>>())
;
// clang-format on
options.parse_positional({"filepath"});
auto args = options.parse(argc, argv);
if (args.count("help")) {
std::cout << options.help() << std::endl;
exit(0);
}
const auto filepath = args["filepath"].as<std::string>();
bool is_file = std::filesystem::is_regular_file(filepath);
bool is_cpp_file = std::filesystem::path(filepath).extension().string() == ".cpp";
// Inform the Rerun Viewer that we do not support that kind of file.
if (!is_file || !is_cpp_file) {
return rerun::EXTERNAL_IMPORTER_INCOMPATIBLE_EXIT_CODE;
}
std::ifstream file(filepath);
std::stringstream body;
body << file.rdbuf();
std::string text = "## Some C++ code\n```cpp\n" + body.str() + "\n```\n";
auto application_id = std::string_view("rerun_example_external_importer");
if (args.count("application-id")) {
application_id = args["application-id"].as<std::string>();
}
auto recording_id = std::string_view();
if (args.count("recording-id")) {
recording_id = args["recording-id"].as<std::string>();
}
const auto rec = rerun::RecordingStream(application_id, recording_id);
// The most important part of this: log to standard output so the Rerun Viewer can ingest it!
rec.to_stdout().exit_on_failure();
set_time_from_args(rec, args);
auto entity_path = std::string(filepath);
if (args.count("entity-path-prefix")) {
entity_path = args["entity-path-prefix"].as<std::string>() + "/" + filepath;
}
rec.log_with_static(
entity_path,
args["static"].as<bool>(),
rerun::TextDocument(text).with_media_type(rerun::MediaType::markdown())
);
}
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_incremental_logging main.cpp)
rerun_strict_warning_settings(example_incremental_logging)
else()
project(example_incremental_logging LANGUAGES CXX)
add_executable(example_incremental_logging main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
# Link against rerun_sdk.
target_link_libraries(example_incremental_logging PRIVATE rerun_sdk)
@@ -0,0 +1,26 @@
<!--[metadata]
title = "Incremental logging"
tags = ["3D", "API Example"]
thumbnail = "https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/480w.png"
thumbnail_dimensions = [480, 301]
-->
Showcases how to incrementally log data belonging to the same archetype, and re-use some or all of it across frames.
<picture>
<img src="https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/incremental_logging/b7a2bd889b09c3840f56dc31bd6d677934ab3126/1200w.png">
</picture>
## Run the code
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_incremental_logging
./examples/cpp/incremental/example_incremental_logging
```
+72
View File
@@ -0,0 +1,72 @@
// Showcase how to incrementally log data belonging to the same archetype, and re-use some or all
// of it across frames.
#include <rerun.hpp>
#include <algorithm>
#include <random>
static const char* README = R"(
# Incremental Logging
This example showcases how to incrementally log data belonging to the same archetype, and re-use some or all of it across frames.
It was logged with the following code:
```cpp
std::vector<rerun::Color> colors(10, rerun::Color(255, 0, 0));
std::vector<rerun::Radius> radii(10, rerun::Radius(0.1f));
// Only log colors and radii once.
rec.set_time_sequence("frame_nr", 0);
rec.log("points", colors, radii);
std::default_random_engine gen;
std::uniform_real_distribution<float> dist_pos(-5.0f, 5.0f);
// Then log only the points themselves each frame.
//
// They will automatically re-use the colors and radii logged at the beginning.
for (int i = 0; i < 10; ++i) {
rec.set_time_sequence("frame_nr", i);
std::vector<rerun::Position3D> points(10);
std::generate(points.begin(), points.end(), [&] {
return rerun::Position3D(dist_pos(gen), dist_pos(gen), dist_pos(gen));
});
rec.log("points", rerun::Points3D(points));
}
```
Move the time cursor around, and notice how the colors and radii from frame 0 are still picked up by later frames, while the points themselves keep changing every frame.
)";
int main() {
const auto rec = rerun::RecordingStream("rerun_example_incremental_logging");
rec.spawn().exit_on_failure();
rec.log_static(
"readme",
rerun::TextDocument(README).with_media_type(rerun::components::MediaType::markdown())
);
// Only log colors and radii once.
// Logging statically with `RecordingStream::log_static` would also work.
rec.set_time_sequence("frame_nr", 0);
rec.log("points", rerun::Points3D().with_colors(rerun::Color(255, 0, 0)).with_radii(0.1f));
std::default_random_engine gen;
std::uniform_real_distribution<float> dist_pos(-5.0f, 5.0f);
// Then log only the points themselves each frame.
//
// They will automatically re-use the colors and radii logged at the beginning.
for (int i = 0; i < 10; ++i) {
rec.set_time_sequence("frame_nr", i);
std::vector<rerun::Position3D> points(10);
std::generate(points.begin(), points.end(), [&] {
return rerun::Position3D(dist_pos(gen), dist_pos(gen), dist_pos(gen));
});
rec.log("points", rerun::Points3D::update_fields().with_positions(points));
}
}
+43
View File
@@ -0,0 +1,43 @@
<!--[metadata]
title = "KISS-ICP"
tags = ["3D", "Point cloud"]
source = "https://github.com/rerun-io/kiss-icp"
thumbnail = "https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/480w.png"
thumbnail_dimensions = [480, 288]
-->
Visualizes the KISS-ICP LiDAR odometry pipeline on the NCLT dataset.
Estimating the odometry is a common problem in robotics and in the [2023, "KISS-ICP: In Defense of Point-to-Point ICP -- Simple, Accurate, and Robust Registration If Done the Right Way" Ignacio Vizzo et al.](https://arxiv.org/abs/2209.15397) they show how one can use an ICP (iterative closest point) algorithm to robustly and accurately estimate poses from LiDAR data. We will demonstrate the KISS-ICP pipeline on the [NCLT dataset](http://robots.engin.umich.edu/nclt/) along with some brief explanations, for a more detailed explanation you should look at the [original paper](https://arxiv.org/abs/2209.15397).
<picture>
<img src="https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/kiss-icp-screenshot/881ec7c7c0a0e50ec5d78d82875efaf3bb3c6e01/1200w.png">
</picture>
The KISS-ICP odometry pipeline consists of 4 steps. The first step is to compensate for movement of the vehicle during the LiDAR scan which is commonly called deskewing. This is done by creating an estimate of the rotational and translational velocity from previous pose estimates, then calculate the corrected scan under the assumption that the velocity is constant. In the screenshot below the raw scan is shown as green and the corrected scan is shown as the blue.
<picture>
<img src="https://static.rerun.io/kiss-icp-deskewing/7157b0427d5358b18c5cf822669dc40601a1d4b6/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/kiss-icp-deskewing/7157b0427d5358b18c5cf822669dc40601a1d4b6/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/kiss-icp-deskewing/7157b0427d5358b18c5cf822669dc40601a1d4b6/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/kiss-icp-deskewing/7157b0427d5358b18c5cf822669dc40601a1d4b6/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/kiss-icp-deskewing/7157b0427d5358b18c5cf822669dc40601a1d4b6/1200w.png">
</picture>
The second step is to subsample the deskewed point cloud at two different resolutions. The first subsample with the highest resolution iis used to update the map after the pose has been estimated. The second is a subsample of the first subsample but with a lower resolution, this subsample is used during the ICP registration step. In the screenshot below the first subsample is colored pink and the second subsample is colored purple.
<picture>
<img src="https://static.rerun.io/kiss-icp-subsampling/31eecf16f5f4d658a7391e051ead948cb0305913/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/kiss-icp-subsampling/31eecf16f5f4d658a7391e051ead948cb0305913/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/kiss-icp-subsampling/31eecf16f5f4d658a7391e051ead948cb0305913/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/kiss-icp-subsampling/31eecf16f5f4d658a7391e051ead948cb0305913/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/kiss-icp-subsampling/31eecf16f5f4d658a7391e051ead948cb0305913/1200w.png">
</picture>
The third step is to compute the adaptive threshold which will impose a limit on the distance between correspondences during the ICP. This is done using previously estimated poses to compute a likely limit of the displacement. The final step is to estimate the current pose by doing Point-to-Point ICP. This involves comparing each point in the subsampled scan with the closest point in the constructed map and making incremental updates to the estimated odometry based on these correspondences.
https://vimeo.com/923395317?autoplay=1&loop=1&autopause=0&background=1&muted=1&ratio=1920:1080
+29
View File
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_log_file main.cpp)
rerun_strict_warning_settings(example_log_file)
else()
project(example_log_file LANGUAGES CXX)
add_executable(example_log_file main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)
if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
endif()
# Link against rerun_sdk.
target_link_libraries(example_log_file PRIVATE rerun_sdk)
+12
View File
@@ -0,0 +1,12 @@
<!--[metadata]
title = "Log file example"
-->
Demonstrates how to log any file from the SDK using the [`Importer`](https://www.rerun.io/docs/concepts/logging-and-ingestion/importers/overview) machinery.
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_log_file
./examples/cpp/log_file/example_log_file examples/assets/
```
+80
View File
@@ -0,0 +1,80 @@
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <rerun.hpp>
#include <rerun/third_party/cxxopts.hpp>
int main(int argc, char** argv) {
// Create a new `RecordingStream` which sends data over gRPC to the viewer process.
const auto rec = rerun::RecordingStream("rerun_example_log_file");
cxxopts::Options options(
"rerun_example_log_file",
"Demonstrates how to log any file from the SDK using the `Importer` machinery."
);
// clang-format off
options.add_options()
("h,help", "Print usage")
// Rerun
("spawn", "Start a new Rerun Viewer process and feed it data in real-time")
("connect", "Connects and sends the logged data to a remote Rerun viewer")
("save", "Log data to an rrd file", cxxopts::value<std::string>())
("stdout", "Log data to standard output, to be piped into a Rerun Viewer")
// Example
("from-contents", "Log the contents of the file directly (files only -- not supported by external loaders)", cxxopts::value<bool>()->default_value("false"))
("filepaths", "The filepaths to be loaded and logged", cxxopts::value<std::vector<std::string>>())
;
// clang-format on
options.parse_positional({"filepaths"});
auto args = options.parse(argc, argv);
if (args.count("help")) {
std::cout << options.help() << std::endl;
exit(0);
}
// TODO(#4602): need common rerun args helper library
if (args["spawn"].as<bool>()) {
rec.spawn().exit_on_failure();
} else if (args["connect"].as<bool>()) {
rec.connect_grpc().exit_on_failure();
} else if (args["stdout"].as<bool>()) {
rec.to_stdout().exit_on_failure();
} else if (args.count("save")) {
rec.save(args["save"].as<std::string>()).exit_on_failure();
} else {
rec.spawn().exit_on_failure();
}
const auto from_contents = args["from-contents"].as<bool>();
if (args.count("filepaths")) {
const auto filepaths = args["filepaths"].as<std::vector<std::string>>();
for (const auto& filepath : filepaths) {
if (!from_contents) {
// Either log the file using its path…
rec.log_file_from_path(filepath, "log_file_example");
} else {
// …or using its contents if you already have them loaded for some reason.
if (std::filesystem::is_regular_file(filepath)) {
std::ifstream file(filepath);
std::stringstream contents;
contents << file.rdbuf();
const auto data = contents.str();
rec.log_file_from_contents(
filepath,
reinterpret_cast<const std::byte*>(data.c_str()),
data.size(),
"log_file_example"
);
}
}
}
}
}
+29
View File
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_minimal main.cpp)
rerun_strict_warning_settings(example_minimal)
else()
project(example_minimal LANGUAGES CXX)
add_executable(example_minimal main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)
if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
endif()
# Link against rerun_sdk.
target_link_libraries(example_minimal PRIVATE rerun_sdk)
+24
View File
@@ -0,0 +1,24 @@
<!--[metadata]
title = "Minimal example"
thumbnail = "https://static.rerun.io/minimal-example/9e694c0689f20323ed0053506a7a099f7391afca/480w.png"
thumbnail_dimensions = [480, 480]
-->
<picture>
<source media="(max-width: 480px)" srcset="https://static.rerun.io/minimal/0e47ac513ab25d56cf2b493128097d499a07e5e8/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/minimal/0e47ac513ab25d56cf2b493128097d499a07e5e8/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/minimal/0e47ac513ab25d56cf2b493128097d499a07e5e8/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/minimal/0e47ac513ab25d56cf2b493128097d499a07e5e8/1200w.png">
<img src="https://static.rerun.io/minimal/0e47ac513ab25d56cf2b493128097d499a07e5e8/full.png" alt="Minimal example screenshot">
</picture>
The simplest example of how to use Rerun, showing how to log a point cloud.
This is part of the [Quick Start guide](https://www.rerun.io/docs/getting-started/data-in/cpp).
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_minimal
./examples/cpp/minimal/example_minimal
```
+18
View File
@@ -0,0 +1,18 @@
#include <rerun.hpp>
#include <rerun/demo_utils.hpp>
using rerun::demo::grid3d;
int main() {
// Create a new `RecordingStream` which sends data over gRPC to the viewer process.
const auto rec = rerun::RecordingStream("rerun_example_cpp");
// Try to spawn a new viewer instance.
rec.spawn().exit_on_failure();
// Create some data using the `grid` utility function.
std::vector<rerun::Position3D> points = grid3d<rerun::Position3D, float>(-10.f, 10.f, 10);
std::vector<rerun::Color> colors = grid3d<rerun::Color, uint8_t>(0, 255, 10);
// Log the "my_points" entity with our data, using the `Points3D` archetype.
rec.log("my_points", rerun::Points3D(points).with_colors(colors).with_radii({0.5f}));
}
+27
View File
@@ -0,0 +1,27 @@
<!--[metadata]
title = "ROS 2 bridge"
source = "https://github.com/rerun-io/cpp-example-ros2-bridge"
tags = ["2D", "3D", "Pinhole camera", "ROS", "Time series", "C++"]
thumbnail = "https://static.rerun.io/carla_thumbnail/8ec07c28f8eb901b8246afdd0b6d2b97ff75fb8d/480w.png"
thumbnail_dimensions = [480, 480]
-->
A proof-of-concept Rerun bridge for ROS 2 that subscribes to all supported topics and visualizes the messages in Rerun.
https://vimeo.com/940929187?autoplay=1&loop=1&autopause=0&background=1&muted=1&ratio=2696:1552
## Background
This is an example that shows how to use Rerun's C++ API to log and visualize [ROS 2](https://www.ros.org/) messages.
It works by subscribing to all topics with supported types, converting the messages, and logging the data to Rerun. It further allows to remap topic names to specific entity paths, specify additional static transforms, and pinhole parameters via an external config file. See the [launch](https://github.com/rerun-io/cpp-example-ros2-bridge/tree/main/rerun_bridge/launch) directory for usage examples.
## Run the code
This is an external example, check the [repository](https://github.com/rerun-io/cpp-example-ros2-bridge) for more information.
In a nutshell, clone the repo and run a demo with:
```
pixi run carla_example
```
+36
View File
@@ -0,0 +1,36 @@
<!--[metadata]
title = "ROS bridge"
source = "https://github.com/rerun-io/cpp-example-ros-bridge"
tags = ["2D", "3D", "Mesh", "Pinhole camera", "ROS", "Time series", "C++"]
thumbnail = "https://static.rerun.io/ros_bridge/121f72ebaea57a1b895196a5587fd1a428a9fd0e/480w.png"
thumbnail_dimensions = [480, 480]
-->
A proof-of-concept Rerun bridge for ROS 1 that subscribes to all supported topics and visualizes the messages in Rerun.
## Background
This is an example that shows how to use Rerun's C++ API to log and visualize [ROS](https://www.ros.org/) messages.
It works by subscribing to all topics with supported types, converting the messages, and logging the data to Rerun. It further allows to remap topic names to specific entity paths, specify additional static transforms, and pinhole parameters via an external config file. See the [launch](https://github.com/rerun-io/cpp-example-ros-bridge/tree/main/rerun_bridge/launch) directory for usage examples.
<picture>
<img src="https://static.rerun.io/ros_bridge_screenshot/42bcbe797ff18079678b08a6ee0551fcdb7f054b/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/ros_bridge_screenshot/42bcbe797ff18079678b08a6ee0551fcdb7f054b/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/ros_bridge_screenshot/42bcbe797ff18079678b08a6ee0551fcdb7f054b/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/ros_bridge_screenshot/42bcbe797ff18079678b08a6ee0551fcdb7f054b/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/ros_bridge_screenshot/42bcbe797ff18079678b08a6ee0551fcdb7f054b/1200w.png">
</picture>
## Run the code
This is an external example, check the [repository](https://github.com/rerun-io/cpp-example-ros-bridge) for more information.
In a nutshell, clone the repo and run a demo with:
```
pixi run {spot_,drone_}example
```
Note that this example currently supports Linux only.
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_shared_recording main.cpp)
rerun_strict_warning_settings(example_shared_recording)
else()
project(example_shared_recording LANGUAGES CXX)
add_executable(example_shared_recording main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)
if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
endif()
# Link against rerun_sdk.
target_link_libraries(example_shared_recording PRIVATE rerun_sdk)
+25
View File
@@ -0,0 +1,25 @@
<!--[metadata]
title = "Shared recording"
-->
<picture>
<img src="https://static.rerun.io/shared_recording/c3da85f1d4c158b8c7afb6bd3278db000b58049d/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/shared_recording/c3da85f1d4c158b8c7afb6bd3278db000b58049d/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/shared_recording/c3da85f1d4c158b8c7afb6bd3278db000b58049d/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/shared_recording/c3da85f1d4c158b8c7afb6bd3278db000b58049d/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/shared_recording/c3da85f1d4c158b8c7afb6bd3278db000b58049d/1200w.png">
</picture>
This example demonstrates how to use `RecordingId`s to create a single shared recording across multiple processes.
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_shared_recording
```
Run the following multiple times, and you'll see that each invocation adds data to the existing recording rather than creating a new one:
```bash
./examples/cpp/shared_recording/example_shared_recording
```
+24
View File
@@ -0,0 +1,24 @@
#include <iostream>
#include <sstream>
#if defined(WIN32)
#include <process.h>
#define getpid _getpid
#else
#include <unistd.h>
#endif
#include <rerun.hpp>
#include <rerun/demo_utils.hpp>
using rerun::demo::grid3d;
int main() {
const auto rec =
rerun::RecordingStream("rerun_example_shared_recording", "my_shared_recording");
rec.spawn().exit_on_failure();
rec.log("updates", rerun::TextLog(std::string("Hello from ") + std::to_string(getpid())));
std::cout << "Run me again to append more data to the recording!" << std::endl;
}
+24
View File
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_spawn_viewer main.cpp)
rerun_strict_warning_settings(example_spawn_viewer)
else()
project(example_spawn_viewer LANGUAGES CXX)
add_executable(example_spawn_viewer main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
# Link against rerun_sdk.
target_link_libraries(example_spawn_viewer PRIVATE rerun_sdk)
+13
View File
@@ -0,0 +1,13 @@
<!--[metadata]
title = "Spawn Viewer"
tags = ["Spawn"]
-->
Shows how to spawn a new Rerun Viewer process ready to listen for gRPC connections using an executable available in PATH.
```bash
cmake .
cmake --build . --target spawn_viewer
./examples/cpp/spawn_viewer/spawn_viewer
```
+5
View File
@@ -0,0 +1,5 @@
#include <rerun.hpp>
int main() {
rerun::spawn().exit_on_failure();
}
+29
View File
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.16...3.27)
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_stdio main.cpp)
rerun_strict_warning_settings(example_stdio)
else()
project(example_stdio LANGUAGES CXX)
add_executable(example_stdio main.cpp)
# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)
if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()
endif()
# Link against rerun_sdk.
target_link_libraries(example_stdio PRIVATE rerun_sdk)
+23
View File
@@ -0,0 +1,23 @@
<!--[metadata]
title = "Standard Input/Output example"
thumbnail = "https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/480w.png"
thumbnail_dimensions = [480, 298]
-->
<picture>
<img src="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/1200w.png">
</picture>
Demonstrates how to log data to standard output with the Rerun SDK, and then visualize it from standard input with the Rerun Viewer.
To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_stdio
echo 'hello from stdin!' | ./examples/cpp/stdio/example_stdio | rerun -
```
+17
View File
@@ -0,0 +1,17 @@
#include <iostream>
#include <string>
#include <rerun.hpp>
int main() {
const auto rec = rerun::RecordingStream("rerun_example_stdio");
rec.to_stdout().exit_on_failure();
std::string input;
std::string line;
while (std::getline(std::cin, line)) {
input += line + '\n';
}
rec.log("stdin", rerun::TextDocument(input));
}
+182
View File
@@ -0,0 +1,182 @@
<!--[metadata]
title = "Stereo vision SLAM"
source = "https://github.com/rerun-io/StereoVision-SLAM"
tags = ["3D", "Point cloud", "C++"]
thumbnail = "https://static.rerun.io/stereovision_slam/c36cfcf8bc7ec9f03b40559d596d7fee97907ba8/480w.png"
thumbnail_dimensions = [480, 273]
-->
Visualizes stereo vision SLAM on the [KITTI dataset](https://www.cvlibs.net/datasets/kitti/).
<picture>
<img src="https://static.rerun.io/stereovision_slam_full/675db4870c12da348552ac9bcdf4c60228d77322/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/stereovision_slam_full/675db4870c12da348552ac9bcdf4c60228d77322/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/stereovision_slam_full/675db4870c12da348552ac9bcdf4c60228d77322/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/stereovision_slam_full/675db4870c12da348552ac9bcdf4c60228d77322/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/stereovision_slam_full/675db4870c12da348552ac9bcdf4c60228d77322/1200w.png">
</picture>
# Used Rerun types
[`Image`](https://www.rerun.io/docs/reference/types/archetypes/image), [`LineStrips3D`](https://rerun.io/docs/reference/types/archetypes/line_strips3d), [`Scalars`](https://rerun.io/docs/reference/types/archetypes/scalars), [`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d), [`Pinhole`](https://rerun.io/docs/reference/types/archetypes/pinhole), [`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d), [`TextLog`](https://rerun.io/docs/reference/types/archetypes/text_log)
# Background
This example shows [farhad-dalirani's stereo visual SLAM implementation](https://github.com/farhad-dalirani/StereoVision-SLAM). It's input is the video footage from a stereo camera and it produces the trajectory of the vehicle and a point cloud of the surrounding environment.
# Logging and visualizing with Rerun
To easily use Opencv/Eigen types and avoid copying images/points when logging to Rerun it uses [`CollectionAdapter`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1CollectionAdapter.html) with the following code:
```cpp
template <>
struct rerun::CollectionAdapter<uint8_t, cv::Mat>
{
/* Adapters to borrow an OpenCV image into Rerun
* images without copying */
Collection<uint8_t> operator()(const cv::Mat& img)
{
// Borrow for non-temporary.
assert("OpenCV matrix expected have bit depth CV_U8" && CV_MAT_DEPTH(img.type()) == CV_8U);
return Collection<uint8_t>::borrow(img.data, img.total() * img.channels());
}
Collection<uint8_t> operator()(cv::Mat&& img)
{
/* Do a full copy for temporaries (otherwise the data
* might be deleted when the temporary is destroyed). */
assert("OpenCV matrix expected have bit depth CV_U8" && CV_MAT_DEPTH(img.type()) == CV_8U);
std::vector<uint8_t> img_vec(img.total() * img.channels());
img_vec.assign(img.data, img.data + img.total() * img.channels());
return Collection<uint8_t>::take_ownership(std::move(img_vec));
}
};
template <>
struct rerun::CollectionAdapter<rerun::Position3D, std::vector<Eigen::Vector3f>>
{
/* Adapters to log eigen vectors as rerun positions*/
Collection<rerun::Position3D> operator()(const std::vector<Eigen::Vector3f>& container)
{
// Borrow for non-temporary.
return Collection<rerun::Position3D>::borrow(container.data(), container.size());
}
Collection<rerun::Position3D> operator()(std::vector<Eigen::Vector3f>&& container)
{
/* Do a full copy for temporaries (otherwise the data
* might be deleted when the temporary is destroyed). */
std::vector<rerun::Position3D> positions(container.size());
memcpy(positions.data(), container.data(), container.size() * sizeof(Eigen::Vector3f));
return Collection<rerun::Position3D>::take_ownership(std::move(positions));
}
};
template <>
struct rerun::CollectionAdapter<rerun::Position3D, Eigen::Matrix3Xf>
{
/* Adapters so we can log an eigen matrix as rerun positions */
// Sanity check that this is binary compatible.
static_assert(
sizeof(rerun::Position3D) == sizeof(Eigen::Matrix3Xf::Scalar) * Eigen::Matrix3Xf::RowsAtCompileTime
);
Collection<rerun::Position3D> operator()(const Eigen::Matrix3Xf& matrix)
{
// Borrow for non-temporary.
static_assert(alignof(rerun::Position3D) <= alignof(Eigen::Matrix3Xf::Scalar));
return Collection<rerun::Position3D>::borrow(
// Cast to void because otherwise Rerun will try to do above sanity checks with the wrong type (scalar).
reinterpret_cast<const void*>(matrix.data()),
matrix.cols()
);
}
Collection<rerun::Position3D> operator()(Eigen::Matrix3Xf&& matrix)
{
/* Do a full copy for temporaries (otherwise the
* data might be deleted when the temporary is destroyed). */
std::vector<rerun::Position3D> positions(matrix.cols());
memcpy(positions.data(), matrix.data(), matrix.size() * sizeof(rerun::Position3D));
return Collection<rerun::Position3D>::take_ownership(std::move(positions));
}
};
```
## Images
```cpp
// Draw stereo left image
rec.log(entity_name,
rerun::Image(tensor_shape(kf_sort[0].second->left_img_),
rerun::TensorBuffer::u8(kf_sort[0].second->left_img_)));
```
## Pinhole camera
The camera frames shown in the view is generated by the following code:
```cpp
rec.log(entity_name,
rerun::Transform3D(
rerun::Vec3D(camera_position.data()),
rerun::Mat3x3(camera_orientation.data()), true)
);
// …
rec.log(entity_name,
rerun::Pinhole::from_focal_length_and_resolution({fx, fy}, {img_num_cols, img_num_rows}));
```
## Time series
```cpp
void Viewer::Plot(std::string plot_name, double value, unsigned long maxkeyframe_id)
{
// …
rec.set_time_sequence("max_keyframe_id", maxkeyframe_id);
rec.log(plot_name, rerun::Scalars(value));
}
```
## Trajectory
```cpp
rec.log("world/path",
rerun::Transform3D(
rerun::Vec3D(camera_position.data()),
rerun::Mat3x3(camera_orientation.data()), true));
std::vector<rerun::datatypes::Vec3D> path;
// …
rec.log("world/path", rerun::LineStrips3D(rerun::LineStrip3D(path)));
```
## Point cloud
```cpp
rec.log("world/landmarks",
rerun::Transform3D(
rerun::Vec3D(camera_position.data()),
rerun::Mat3x3(camera_orientation.data()), true));
std::vector<Eigen::Vector3f> points3d_vector;
// …
rec.log("world/landmarks", rerun::Points3D(points3d_vector));
```
## Text log
```cpp
rec.log("world/log", rerun::TextLog(msg).with_color(log_color.at(log_type)));
// …
rec.log("world/log", rerun::TextLog("Finished"));
```
# Run the code
This is an external example, check the [repository](https://github.com/rerun-io/StereoVision-SLAM) on how to run the code.
+78
View File
@@ -0,0 +1,78 @@
<!--[metadata]
title = "VRS viewer"
source = "https://github.com/rerun-io/cpp-example-vrs"
tags = ["2D", "3D", "VRS", "Viewer", "C++"]
thumbnail = "https://static.rerun.io/vrs/614f0adf0dd31fa01fff0d6eaeae67bbe8ba9af0/480w.png"
thumbnail_dimensions = [480, 482]
-->
<picture>
<img src="https://static.rerun.io/cpp-example-vrs/c765460d4448da27bb9ee2a2a15f092f82a402d2/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/cpp-example-vrs/c765460d4448da27bb9ee2a2a15f092f82a402d2/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/cpp-example-vrs/c765460d4448da27bb9ee2a2a15f092f82a402d2/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/cpp-example-vrs/c765460d4448da27bb9ee2a2a15f092f82a402d2/1024w.png">
</picture>
This is an example that shows how to use Rerun's C++ API to log and view [VRS](https://github.com/facebookresearch/vrs) files.
# Used Rerun types
[`Arrows3D`](https://www.rerun.io/docs/reference/types/archetypes/arrows3d), [`Image`](https://www.rerun.io/docs/reference/types/archetypes/image), [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars), [`TextDocument`](https://www.rerun.io/docs/reference/types/archetypes/text_document)
# Background
This C++ example demonstrates how to visualize VRS files with Rerun.
VRS is a file format optimized to record & playback streams of sensor data, such as images, audio samples, and any other discrete sensors (IMU, temperature, etc), stored in per-device streams of time-stamped records.
# Logging and visualizing with Rerun
The visualizations in this example were created with the following Rerun code:
## 3D arrows
```cpp
void IMUPlayer::log_accelerometer(const std::array<float, 3>& accelMSec2) {
_rec->log(_entity_path + "/accelerometer", rerun::Arrows3D::from_vectors({accelMSec2}));
// … existing code for scalars …
}
```
## Scalars
```cpp
void IMUPlayer::log_accelerometer(const std::array<float, 3>& accelMSec2) {
// … existing code for Arrows3D …
_rec->log(_entity_path + "/accelerometer", rerun::Scalars(accelMSec2));
}
```
```cpp
void IMUPlayer::log_gyroscope(const std::array<float, 3>& gyroRadSec) {
_rec->log(_entity_path + "/gyroscope", rerun::Scalars(gyroRadSec));
}
```
```cpp
void IMUPlayer::log_magnetometer(const std::array<float, 3>& magTesla) {
_rec->log(_entity_path + "/magnetometer", rerun::Scalars(magTesla));
}
```
## Images
```cpp
_rec->log(
_entity_path,
rerun::Image({
frame->getHeight(),
frame->getWidth(),
frame->getSpec().getChannelCountPerPixel()},
frame->getBuffer()
)
);
```
## Text document
```cpp
_rec->log_static(_entity_path + "/configuration", rerun::TextDocument(layout_str));
```
# Run the code
You can find the build instructions here: [C++ Example: VRS Viewer](https://github.com/rerun-io/cpp-example-vrs)