mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-17 19:40:34 +08:00
uorb: use single byte for internal types in o_fields metadata
Reduces flash usage by ~9KB.
This commit is contained in:
@@ -362,15 +362,6 @@ void LoggedTopics::add_mission_topic(const char *name, uint16_t interval_ms)
|
||||
|
||||
bool LoggedTopics::add_topic(const orb_metadata *topic, uint16_t interval_ms, uint8_t instance)
|
||||
{
|
||||
size_t fields_len = strlen(topic->o_fields) + strlen(topic->o_name) + 1; //1 for ':'
|
||||
|
||||
if (fields_len > sizeof(ulog_message_format_s::format)) {
|
||||
PX4_WARN("skip topic %s, format string is too large: %zu (max is %zu)", topic->o_name, fields_len,
|
||||
sizeof(ulog_message_format_s::format));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_subscriptions.count >= MAX_TOPICS_NUM) {
|
||||
PX4_WARN("Too many subscriptions, failed to add: %s %" PRIu8, topic->o_name, instance);
|
||||
return false;
|
||||
|
||||
@@ -1626,7 +1626,37 @@ void Logger::write_format(LogType type, const orb_metadata &meta, WrittenFormats
|
||||
PX4_DEBUG("writing format for %s", meta.o_name);
|
||||
|
||||
// Write the current format (we don't need to check if we already added it to written_formats)
|
||||
int format_len = snprintf(msg.format, sizeof(msg.format), "%s:%s", meta.o_name, meta.o_fields);
|
||||
int format_len = snprintf(msg.format, sizeof(msg.format), "%s:", meta.o_name);
|
||||
|
||||
for (int format_idx = 0; meta.o_fields[format_idx] != 0;) {
|
||||
const char *end_field = strchr(meta.o_fields + format_idx, ';');
|
||||
|
||||
if (!end_field) {
|
||||
PX4_ERR("Format error in %s", meta.o_fields);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *c_type = orb_get_c_type(meta.o_fields[format_idx]);
|
||||
|
||||
if (c_type) {
|
||||
format_len += snprintf(msg.format + format_len, sizeof(msg.format) - format_len, "%s", c_type);
|
||||
++format_idx;
|
||||
}
|
||||
|
||||
int len = end_field - (meta.o_fields + format_idx) + 1;
|
||||
|
||||
if (len >= (int)sizeof(msg.format) - format_len) {
|
||||
PX4_WARN("skip topic %s, format string is too large, max is %zu", meta.o_name,
|
||||
sizeof(ulog_message_format_s::format));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(msg.format + format_len, meta.o_fields + format_idx, len);
|
||||
format_len += len;
|
||||
format_idx += len;
|
||||
}
|
||||
|
||||
msg.format[format_len] = '\0';
|
||||
size_t msg_size = sizeof(msg) - sizeof(msg.format) + format_len;
|
||||
msg.msg_size = msg_size - ULOG_MSG_HEADER_LEN;
|
||||
|
||||
@@ -1637,7 +1667,7 @@ void Logger::write_format(LogType type, const orb_metadata &meta, WrittenFormats
|
||||
}
|
||||
|
||||
// Now go through the fields and check for nested type usages.
|
||||
// o_fields looks like this for example: "uint64_t timestamp;uint8_t[5] array;"
|
||||
// o_fields looks like this for example: "<chr> timestamp;<chr>[5] array;"
|
||||
const char *fmt = meta.o_fields;
|
||||
|
||||
while (fmt && *fmt) {
|
||||
@@ -1670,20 +1700,7 @@ void Logger::write_format(LogType type, const orb_metadata &meta, WrittenFormats
|
||||
type_name[type_length] = '\0';
|
||||
|
||||
// ignore built-in types
|
||||
if (strcmp(type_name, "int8_t") != 0 &&
|
||||
strcmp(type_name, "uint8_t") != 0 &&
|
||||
strcmp(type_name, "int16_t") != 0 &&
|
||||
strcmp(type_name, "uint16_t") != 0 &&
|
||||
strcmp(type_name, "int16_t") != 0 &&
|
||||
strcmp(type_name, "uint16_t") != 0 &&
|
||||
strcmp(type_name, "int32_t") != 0 &&
|
||||
strcmp(type_name, "uint32_t") != 0 &&
|
||||
strcmp(type_name, "int64_t") != 0 &&
|
||||
strcmp(type_name, "uint64_t") != 0 &&
|
||||
strcmp(type_name, "float") != 0 &&
|
||||
strcmp(type_name, "double") != 0 &&
|
||||
strcmp(type_name, "bool") != 0 &&
|
||||
strcmp(type_name, "char") != 0) {
|
||||
if (orb_get_c_type(type_name[0]) == nullptr) {
|
||||
|
||||
// find orb meta for type
|
||||
const orb_metadata *const *topics = orb_get_topics();
|
||||
|
||||
@@ -336,6 +336,36 @@ Replay::readFormat(std::ifstream &file, uint16_t msg_size)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string Replay::parseOrbFields(const string &fields)
|
||||
{
|
||||
string ret{};
|
||||
|
||||
// convert o_fields from "<chr> timestamp;<chr>[5] array;" to "uint64_t timestamp;int8_t[5] array;"
|
||||
for (int format_idx = 0; format_idx < (int)fields.length();) {
|
||||
const char *end_field = strchr(fields.c_str() + format_idx, ';');
|
||||
|
||||
if (!end_field) {
|
||||
PX4_ERR("Format error in %s", fields.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
const char *c_type = orb_get_c_type(fields[format_idx]);
|
||||
|
||||
if (c_type) {
|
||||
string str_type = c_type;
|
||||
ret += str_type;
|
||||
++format_idx;
|
||||
}
|
||||
|
||||
int len = end_field - (fields.c_str() + format_idx) + 1;
|
||||
ret += fields.substr(format_idx, len);
|
||||
format_idx += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
Replay::readAndAddSubscription(std::ifstream &file, uint16_t msg_size)
|
||||
{
|
||||
@@ -371,12 +401,12 @@ Replay::readAndAddSubscription(std::ifstream &file, uint16_t msg_size)
|
||||
// FIXME: this should check recursively, all used nested types
|
||||
string file_format = _file_formats[topic_name];
|
||||
|
||||
std::string orb_fields(orb_meta->o_fields);
|
||||
const string orb_fields = parseOrbFields(orb_meta->o_fields);
|
||||
|
||||
if (file_format != orb_fields) {
|
||||
// check if we have a compatibility conversion available
|
||||
if (topic_name == "sensor_combined") {
|
||||
if (string(orb_meta->o_fields) == "uint64_t timestamp;float[3] gyro_rad;uint32_t gyro_integral_dt;"
|
||||
if (orb_fields == "uint64_t timestamp;float[3] gyro_rad;uint32_t gyro_integral_dt;"
|
||||
"int32_t accelerometer_timestamp_relative;float[3] accelerometer_m_s2;"
|
||||
"uint32_t accelerometer_integral_dt" &&
|
||||
file_format == "uint64_t timestamp;float[3] gyro_rad;float gyro_integral_dt;"
|
||||
@@ -390,9 +420,9 @@ Replay::readAndAddSubscription(std::ifstream &file, uint16_t msg_size)
|
||||
int unused;
|
||||
|
||||
if (findFieldOffset(file_format, "gyro_integral_dt", gyro_integral_dt_offset_log, unused) &&
|
||||
findFieldOffset(orb_meta->o_fields, "gyro_integral_dt", gyro_integral_dt_offset_intern, unused) &&
|
||||
findFieldOffset(orb_fields, "gyro_integral_dt", gyro_integral_dt_offset_intern, unused) &&
|
||||
findFieldOffset(file_format, "accelerometer_integral_dt", accelerometer_integral_dt_offset_log, unused) &&
|
||||
findFieldOffset(orb_meta->o_fields, "accelerometer_integral_dt", accelerometer_integral_dt_offset_intern, unused)) {
|
||||
findFieldOffset(orb_fields, "accelerometer_integral_dt", accelerometer_integral_dt_offset_intern, unused)) {
|
||||
|
||||
compat = new CompatSensorCombinedDtType(gyro_integral_dt_offset_log, gyro_integral_dt_offset_intern,
|
||||
accelerometer_integral_dt_offset_log, accelerometer_integral_dt_offset_intern);
|
||||
@@ -449,7 +479,7 @@ Replay::readAndAddSubscription(std::ifstream &file, uint16_t msg_size)
|
||||
|
||||
//find the timestamp offset
|
||||
int field_size;
|
||||
bool timestamp_found = findFieldOffset(orb_meta->o_fields, "timestamp", subscription->timestamp_offset, field_size);
|
||||
bool timestamp_found = findFieldOffset(orb_fields, "timestamp", subscription->timestamp_offset, field_size);
|
||||
|
||||
if (!timestamp_found) {
|
||||
delete subscription;
|
||||
|
||||
@@ -277,6 +277,8 @@ private:
|
||||
|
||||
void setUserParams(const char *filename);
|
||||
|
||||
std::string parseOrbFields(const std::string &fields);
|
||||
|
||||
static char *_replay_file;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user