mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 07:28:54 +08:00
uorb: add message format compatibility check
This can be used by DDS/ROS 2 to check for matching message definitions.
This commit is contained in:
@@ -171,6 +171,61 @@ def get_children_fields(base_type, search_path):
|
||||
return spec_temp.parsed_fields()
|
||||
|
||||
|
||||
def get_message_fields_str_for_message_hash(msg_fields, search_path):
|
||||
"""
|
||||
Get all fields (including for nested types) in the form of:
|
||||
'''
|
||||
uint64 timestamp
|
||||
uint8 esc_count
|
||||
uint8 esc_online_flags
|
||||
EscReport[8] esc
|
||||
uint64 timestamp
|
||||
uint32 esc_errorcount
|
||||
int32 esc_rpm
|
||||
float32 esc_voltage
|
||||
uint16 failures
|
||||
int8 esc_power
|
||||
'''
|
||||
"""
|
||||
all_fields_str = ''
|
||||
for field in msg_fields:
|
||||
if field.is_header:
|
||||
continue
|
||||
|
||||
type_name = field.type
|
||||
# detect embedded types
|
||||
sl_pos = type_name.find('/')
|
||||
if sl_pos >= 0:
|
||||
type_name = type_name[sl_pos + 1:]
|
||||
|
||||
all_fields_str += type_name + ' ' + field.name + '\n'
|
||||
|
||||
if sl_pos >= 0: # nested type, add all nested fields
|
||||
children_fields = get_children_fields(field.base_type, search_path)
|
||||
all_fields_str += get_message_fields_str_for_message_hash(children_fields, search_path)
|
||||
|
||||
return all_fields_str
|
||||
|
||||
|
||||
def hash_32_fnv1a(data: str):
|
||||
hash_val = 0x811c9dc5
|
||||
prime = 0x1000193
|
||||
for i in range(len(data)):
|
||||
value = ord(data[i])
|
||||
hash_val = hash_val ^ value
|
||||
hash_val *= prime
|
||||
hash_val &= 0xffffffff
|
||||
return hash_val
|
||||
|
||||
|
||||
def get_message_hash(msg_fields, search_path):
|
||||
"""
|
||||
Get a 32 bit message hash over all fields
|
||||
"""
|
||||
all_fields_str = get_message_fields_str_for_message_hash(msg_fields, search_path)
|
||||
return hash_32_fnv1a(all_fields_str)
|
||||
|
||||
|
||||
def add_padding_bytes(fields, search_path):
|
||||
"""
|
||||
Add padding fields before the embedded types, at the end and calculate the
|
||||
|
||||
@@ -58,6 +58,7 @@ from px_generate_uorb_topic_helper import * # this is in Tools/
|
||||
|
||||
uorb_struct = '%s_s'%name_snake_case
|
||||
|
||||
message_hash = get_message_hash(spec.parsed_fields(), search_path)
|
||||
sorted_fields = sorted(spec.parsed_fields(), key=sizeof_field_type, reverse=True)
|
||||
struct_size, padding_end_size = add_padding_bytes(sorted_fields, search_path)
|
||||
}@
|
||||
@@ -74,7 +75,7 @@ struct_size, padding_end_size = add_padding_bytes(sorted_fields, search_path)
|
||||
|
||||
@[for topic in topics]@
|
||||
static_assert(static_cast<orb_id_size_t>(ORB_ID::@topic) == @(all_topics.index(topic)), "ORB_ID index mismatch");
|
||||
ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), static_cast<orb_id_size_t>(ORB_ID::@topic));
|
||||
ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), @(message_hash)u, static_cast<orb_id_size_t>(ORB_ID::@topic));
|
||||
@[end for]
|
||||
|
||||
void print_message(const orb_metadata *meta, const @uorb_struct& message)
|
||||
|
||||
Reference in New Issue
Block a user