Skip to content

Commit 9dde7bf

Browse files
chemicstrypatrickelectric
authored andcommitted
Update mavlink definitions
1 parent 1a5997b commit 9dde7bf

5 files changed

Lines changed: 117 additions & 23 deletions

File tree

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
runs-on: ubuntu-latest
3030
strategy:
3131
matrix:
32-
dialect: ["ardupilotmega", "asluav", "matrixpilot", "minimal", "paparazzi", "python_array_test", "slugs", "standard", "test", "ualberta", "uavionix", "icarous", "common"]
32+
dialect: ["ardupilotmega", "asluav", "matrixpilot", "minimal", "paparazzi", "python_array_test", "slugs", "standard", "test", "ualberta", "uavionix", "icarous", "common", "storm32", "csairlink", "loweheiser"]
3333
signing: ["", "--features signing"]
3434
steps:
3535
- uses: actions/checkout@master
@@ -134,4 +134,4 @@ jobs:
134134
if: ${{ github.ref == 'refs/heads/master' }}
135135
with:
136136
github_token: ${{ secrets.GITHUB_TOKEN }}
137-
publish_dir: ./target/doc
137+
publish_dir: ./target/doc

mavlink-bindgen/src/parser.rs

Lines changed: 104 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,25 @@ impl MavProfile {
5353
}
5454

5555
/// Go over all fields in the messages, and if you encounter an enum,
56-
/// update this enum with information about whether it is a bitmask, and what
57-
/// is the desired width of such.
56+
/// which is a bitmask, set the bitmask size based on field size
5857
fn update_enums(mut self) -> Self {
59-
for msg in self.messages.values() {
60-
for field in &msg.fields {
58+
for msg in self.messages.values_mut() {
59+
for field in &mut msg.fields {
6160
if let Some(enum_name) = &field.enumtype {
62-
// it is a bitmask
63-
if let Some("bitmask") = &field.display.as_deref() {
64-
// find the corresponding enum
65-
for enm in self.enums.values_mut() {
66-
if enm.name == *enum_name {
67-
// this is the right enum
68-
enm.bitfield = Some(field.mavtype.rust_primitive_type());
61+
// find the corresponding enum
62+
if let Some(enm) = self.enums.get_mut(enum_name) {
63+
// Handle legacy definition where bitmask is defined as display="bitmask"
64+
if field.display == Some("bitmask".to_string()) {
65+
enm.bitmask = true;
66+
}
67+
68+
// it is a bitmask
69+
if enm.bitmask {
70+
enm.primitive = Some(field.mavtype.rust_primitive_type());
71+
72+
// Fix fields in backwards manner
73+
if field.display.is_none() {
74+
field.display = Some("bitmask".to_string());
6975
}
7076
}
7177
}
@@ -310,8 +316,11 @@ pub struct MavEnum {
310316
pub name: String,
311317
pub description: Option<String>,
312318
pub entries: Vec<MavEnumEntry>,
313-
/// If contains Some, the string represents the type witdh for bitflags
314-
pub bitfield: Option<String>,
319+
/// If contains Some, the string represents the primitive type (size) for bitflags.
320+
/// If no fields use this enum, the bitmask is true, but primitive is None. In this case
321+
/// regular enum is generated as primitive is unknown.
322+
pub primitive: Option<String>,
323+
pub bitmask: bool,
315324
}
316325

317326
impl MavEnum {
@@ -356,7 +365,7 @@ impl MavEnum {
356365
let tmp = TokenStream::from_str(&tmp_value.to_string()).unwrap();
357366
value = quote!(#tmp);
358367
};
359-
if self.bitfield.is_some() {
368+
if self.primitive.is_some() {
360369
quote! {
361370
#description
362371
const #name = #value;
@@ -398,14 +407,14 @@ impl MavEnum {
398407
let description = quote!();
399408

400409
let enum_def;
401-
if let Some(width) = self.bitfield.clone() {
402-
let width = format_ident!("{}", width);
410+
if let Some(primitive) = self.primitive.clone() {
411+
let primitive = format_ident!("{}", primitive);
403412
enum_def = quote! {
404413
bitflags!{
405414
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
406415
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
407416
#description
408-
pub struct #enum_name: #width {
417+
pub struct #enum_name: #primitive {
409418
#(#defs)*
410419
}
411420
}
@@ -1171,6 +1180,8 @@ pub fn parse_profile(
11711180
if attr.key.into_inner() == b"name" {
11721181
mavenum.name = to_pascal_case(attr.value);
11731182
//mavenum.name = attr.value.clone();
1183+
} else if attr.key.into_inner() == b"bitmask" {
1184+
mavenum.bitmask = true;
11741185
}
11751186
}
11761187
Some(&MavXmlElement::Entry) => {
@@ -1230,8 +1241,16 @@ pub fn parse_profile(
12301241
field.mavtype = MavType::parse_type(&r#type).unwrap();
12311242
}
12321243
b"enum" => {
1233-
field.enumtype = Some(to_pascal_case(attr.value));
1234-
//field.enumtype = Some(attr.value.clone());
1244+
field.enumtype = Some(to_pascal_case(&attr.value));
1245+
1246+
// Update field display if enum is a bitmask
1247+
if let Some(e) =
1248+
profile.enums.get(field.enumtype.as_ref().unwrap())
1249+
{
1250+
if e.bitmask {
1251+
field.display = Some("bitmask".to_string());
1252+
}
1253+
}
12351254
}
12361255
b"display" => {
12371256
field.display =
@@ -1439,16 +1458,35 @@ struct ExtensionFilter {
14391458
pub is_in: bool,
14401459
}
14411460

1461+
struct MessageFilter {
1462+
pub is_in: bool,
1463+
pub messages: Vec<String>,
1464+
}
1465+
1466+
impl MessageFilter {
1467+
pub fn new() -> Self {
1468+
Self {
1469+
is_in: false,
1470+
messages: vec![
1471+
// device_cap_flags is u32, when enum is u16, which is not handled by the parser yet
1472+
"STORM32_GIMBAL_MANAGER_INFORMATION".to_string(),
1473+
],
1474+
}
1475+
}
1476+
}
1477+
14421478
struct MavXmlFilter {
14431479
#[cfg(not(feature = "emit-extensions"))]
14441480
extension_filter: ExtensionFilter,
1481+
message_filter: MessageFilter,
14451482
}
14461483

14471484
impl Default for MavXmlFilter {
14481485
fn default() -> Self {
14491486
Self {
14501487
#[cfg(not(feature = "emit-extensions"))]
14511488
extension_filter: ExtensionFilter { is_in: false },
1489+
message_filter: MessageFilter::new(),
14521490
}
14531491
}
14541492
}
@@ -1457,6 +1495,7 @@ impl MavXmlFilter {
14571495
pub fn filter(&mut self, elements: &mut Vec<Result<Event, quick_xml::Error>>) {
14581496
// List of filters
14591497
elements.retain(|x| self.filter_extension(x));
1498+
elements.retain(|x| self.filter_messages(x))
14601499
}
14611500

14621501
#[cfg(feature = "emit-extensions")]
@@ -1500,6 +1539,52 @@ impl MavXmlFilter {
15001539
Err(error) => panic!("Failed to filter XML: {error}"),
15011540
}
15021541
}
1542+
1543+
/// Filters messages by their name
1544+
pub fn filter_messages(&mut self, element: &Result<Event, quick_xml::Error>) -> bool {
1545+
match element {
1546+
Ok(content) => {
1547+
match content {
1548+
Event::Start(bytes) | Event::Empty(bytes) => {
1549+
let Some(id) = identify_element(bytes.name().into_inner()) else {
1550+
panic!(
1551+
"unexpected element {:?}",
1552+
String::from_utf8_lossy(bytes.name().into_inner())
1553+
);
1554+
};
1555+
if id == MavXmlElement::Message {
1556+
for attr in bytes.attributes() {
1557+
let attr = attr.unwrap();
1558+
if attr.key.into_inner() == b"name" {
1559+
let value = String::from_utf8_lossy(&attr.value).into_owned();
1560+
if self.message_filter.messages.contains(&value) {
1561+
self.message_filter.is_in = true;
1562+
return false;
1563+
}
1564+
}
1565+
}
1566+
}
1567+
}
1568+
Event::End(bytes) => {
1569+
let Some(id) = identify_element(bytes.name().into_inner()) else {
1570+
panic!(
1571+
"unexpected element {:?}",
1572+
String::from_utf8_lossy(bytes.name().into_inner())
1573+
);
1574+
};
1575+
1576+
if id == MavXmlElement::Message && self.message_filter.is_in {
1577+
self.message_filter.is_in = false;
1578+
return false;
1579+
}
1580+
}
1581+
_ => {}
1582+
}
1583+
!self.message_filter.is_in
1584+
}
1585+
Err(error) => panic!("Failed to filter XML: {error}"),
1586+
}
1587+
}
15031588
}
15041589

15051590
fn to_pascal_case(text: impl AsRef<[u8]>) -> String {

mavlink/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ all = [
5252
"uavionix",
5353
"avssuas",
5454
"cubepilot",
55+
"storm32",
56+
"csairlink",
57+
"loweheiser"
5558
]
5659

5760
ardupilotmega = ["common", "icarous", "uavionix"]
@@ -70,6 +73,9 @@ uavionix = ["common"]
7073
icarous = []
7174
common = []
7275
cubepilot = ["common"]
76+
csairlink = []
77+
loweheiser = ["minimal"]
78+
storm32 = ["ardupilotmega"]
7379

7480
all-dialects = [
7581
"ardupilotmega",
@@ -88,6 +94,9 @@ all-dialects = [
8894
"icarous",
8995
"common",
9096
"cubepilot",
97+
"storm32",
98+
"csairlink",
99+
"loweheiser"
91100
]
92101

93102
format-generated-code = []

mavlink/mavlink

Submodule mavlink updated 47 files

mavlink/tests/test_shared/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub fn get_cmd_nav_takeoff_msg() -> mavlink::common::COMMAND_INT_DATA {
9494
pub fn get_hil_actuator_controls_msg() -> mavlink::common::HIL_ACTUATOR_CONTROLS_DATA {
9595
mavlink::common::HIL_ACTUATOR_CONTROLS_DATA {
9696
time_usec: 1234567_u64,
97-
flags: 0_u64,
97+
flags: mavlink::common::HilActuatorControlsFlags::empty(),
9898
controls: [
9999
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
100100
],

0 commit comments

Comments
 (0)