Skip to content

Commit

Permalink
read-api: Addressed comments from review
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasDebrunner committed Oct 17, 2023
1 parent 1e2273f commit 4752381
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 62 deletions.
81 changes: 49 additions & 32 deletions examples/ulog_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,52 +45,69 @@ int main(int argc, char** argv)
// Read out some data

// List all subscription names
for (const auto& sub : data_container->subscriptionNames()) {
auto subscription_names = data_container->subscriptionNames();
for (const auto& sub : subscription_names) {
std::cout << sub << "\n";
}

// Get a particular subscription
const auto& subscription = data_container->subscription("vehicle_status");
if (subscription_names.find("vehicle_status") != subscription_names.end()) {
const auto& subscription = data_container->subscription("vehicle_status");

// Get message format of subscription
auto message_format = subscription->format();
std::cout << "Message format: " << message_format->name() << "\n";
// Get message format of subscription
auto message_format = subscription->format();
std::cout << "Message format: " << message_format->name() << "\n";

// List all field names
for (const std::string& field : subscription->fieldNames()) {
std::cout << field << "\n";
}
// List all field names
std::cout << "Field names: "
<< "\n";
for (const std::string& field : subscription->fieldNames()) {
std::cout << field << "\n";
}

// Get particular field
auto nav_state_field = subscription->field("nav_state");
// Get particular field
auto nav_state_field = subscription->field("nav_state");

// Iterate over all samples
for (const auto& sample : *subscription) {
// always correctly extracts the type as defined in the message definition,
// gets cast to the value you put in int.
// This also works for arrays and strings.
auto nav_state = sample[nav_state_field].as<int>();
std::cout << nav_state << "\n";
}
// Iterate over all samples
std::cout << "nav_state values: \n";
for (const auto& sample : *subscription) {
// always correctly extracts the type as defined in the message definition,
// gets cast to the value you put in int.
// This also works for arrays and strings.
auto nav_state = sample[nav_state_field].as<int>();
std::cout << nav_state << ", ";
}
std::cout << "\n";

// get a specific sample
auto sample_12 = subscription->at(12);
// get a specific sample
auto sample_12 = subscription->at(12);

// access values by name
auto timestamp = sample_12["timestamp"].as<uint64_t>();
// access values by name
auto timestamp = sample_12["timestamp"].as<uint64_t>();

std::cout << timestamp << "\n";
std::cout << timestamp << "\n";
} else {
std::cout << "No vehicle_status subscription found\n";
}

// get from nested data type
auto esc_format =
data_container->messageFormats().at("esc_status")->field("esc")->type().nested_message;
for (const auto& field_name : esc_format->fieldNames()) {
std::cout << field_name << "\n";
if (data_container->messageFormats().find("esc_status") !=
data_container->messageFormats().end()) {
const auto& message_format = data_container->messageFormats().at("esc_status");
std::cout << "Message format: " << message_format->name() << "\n";
for (const auto& field_name : message_format->fieldNames()) {
std::cout << field_name << "\n";
}
} else {
std::cout << "No esc_status message format found\n";
}

auto esc_status = data_container->subscription("esc_status");
for (const auto& sample : *esc_status) {
std::cout << "timestamp: " << sample["esc"][7]["esc_power"].as<int>() << "\n";
if (subscription_names.find("esc_status") != subscription_names.end()) {
auto esc_status = data_container->subscription("esc_status");
for (const auto& sample : *esc_status) {
std::cout << "esc_power: " << sample["esc"][7]["esc_power"].as<int>() << "\n";
}
} else {
std::cout << "No esc_status subscription found\n";
}
return 0;
}
7 changes: 0 additions & 7 deletions examples/ulog_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,6 @@ int main(int argc, char** argv)
subscriptions.size());
std::transform(subscriptions.begin(), subscriptions.end(), sorted_subscription_keys.begin(),
[](const auto& pair) { return pair.first; });
std::sort(sorted_subscription_keys.begin(), sorted_subscription_keys.end(),
[](const auto& a, const auto& b) {
if (a.name == b.name) {
return a.multi_id < b.multi_id;
}
return a.name < b.name;
});
for (const auto& key : sorted_subscription_keys) {
const auto& subscription = subscriptions.at(key);
printf(" %s (%i) - %zu\n", key.name.c_str(), key.multi_id, subscription->size());
Expand Down
23 changes: 9 additions & 14 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@

include(FetchContent)

set(SYSTEM_ARG SYSTEM)
# cmake < 3.25 fails with system attribute
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25")
FetchContent_Declare(
DocTest
GIT_REPOSITORY "https://github.com/doctest/doctest.git"
GIT_TAG "v2.4.11"
SYSTEM
)

else()
FetchContent_Declare(
DocTest
GIT_REPOSITORY "https://github.com/doctest/doctest.git"
GIT_TAG "v2.4.11"
)
if (CMAKE_VERSION VERSION_LESS "3.25")
set(SYSTEM_ARG "")
endif ()
FetchContent_Declare(
DocTest
GIT_REPOSITORY "https://github.com/doctest/doctest.git"
GIT_TAG "v2.4.11"
${SYSTEM_ARG}
)


FetchContent_MakeAvailable(DocTest)
Expand Down
9 changes: 9 additions & 0 deletions ulog_cpp/data_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ void DataContainer::headerComplete()
message_info.field().resolveDefinition(_message_formats, 0);
}

// try to resolve all fields for all multi message infos
for (auto& it : _message_info_multi) {
for (auto& message_infos_for_field : it.second) {
for (auto& message_info : message_infos_for_field) {
message_info.field().resolveDefinition(_message_formats, 0);
}
}
}

// try to resolve all fields for params
for (auto& it : _default_parameters) {
auto& parameter = it.second;
Expand Down
9 changes: 5 additions & 4 deletions ulog_cpp/data_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <memory>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
Expand All @@ -23,7 +24,7 @@ class DataContainer : public DataHandlerInterface {

struct NameAndMultiIdKey {
std::string name;
int multi_id;
int multi_id{0};

NameAndMultiIdKey() = default;

Expand Down Expand Up @@ -95,13 +96,13 @@ class DataContainer : public DataHandlerInterface {
return _subscriptions_by_message_id;
}

std::vector<std::string> subscriptionNames() const
std::set<std::string> subscriptionNames() const
{
std::unordered_set<std::string> names;
std::set<std::string> names;
for (const auto& kv : _subscriptions_by_name_and_multi_id) {
names.insert(kv.first.name);
}
return std::vector<std::string>(names.begin(), names.end());
return names;
}

std::shared_ptr<Subscription> subscription(const std::string& name, int multi_id) const
Expand Down
6 changes: 3 additions & 3 deletions ulog_cpp/messages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class Field {
* Since these types are only available at runtime, one can get the value as an std::variant,
* and then do appropriate handling for each type. In case the user knows what type to expect,
* it can also be explicitly casted to the desired type. In this case, any type conversion that is
* allowed by `static_cast will` be performed.
* allowed by `static_cast` will be performed.
*
* Array types can be directly extracted as std::vector<T>, string types as std::string.
*/
Expand Down Expand Up @@ -346,7 +346,7 @@ class Value {
// return type is different from native type, but a vector
res.resize(arg.size());
for (std::size_t i = 0; i < arg.size(); i++) {
res[i] = static_cast<typename ReturnType::value_type>(arg[i]);
res[i] = staticCastEnsureUnsignedChar<typename ReturnType::value_type>(arg[i]);
}
}
} else {
Expand All @@ -362,7 +362,7 @@ class Value {
if constexpr (is_vector<ReturnType>::value) {
// return type is a vector
res.resize(1);
res[0] = static_cast<typename ReturnType::value_type>(arg);
res[0] = staticCastEnsureUnsignedChar<typename ReturnType::value_type>(arg);
} else {
// return type is not a vector
res = staticCastEnsureUnsignedChar<ReturnType>(arg);
Expand Down
2 changes: 1 addition & 1 deletion ulog_cpp/reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include "raw_messages.hpp"

#if 1
#if 0
#define DBG_PRINTF(...) printf(__VA_ARGS__)
#else
#define DBG_PRINTF(...)
Expand Down
2 changes: 1 addition & 1 deletion ulog_cpp/subscription.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ulog_cpp {
/**
* TypedDataView is a view on a Data object, which allows to access the data using the
* MessageFormat meta definition. The subscription object only contains the Data object,
* without repeated reference to the underlying MessageFormat, for storage efficiency reason.s
* without repeated reference to the underlying MessageFormat, for storage efficiency reasons.
*
* Note that TypedDataView should be a short-lived object solely to access data. As
* it stores references to the underlying Data and MessageFormat objects, it is only valid
Expand Down

0 comments on commit 4752381

Please sign in to comment.