MAVLink 協議解析之XML定義篇

1 MAVLink XML 文件的基本結構

下面的代碼塊是 mavlink 消息定義的 xml 數據文檔

代碼塊 1

<?xml version="1.0"?>
<mavlink>
  <version>3</version>
  <dialect>0</dialect>
  <enums>
  	<enum name="aaaa">
  	</enum>
  	<enum name="bbbb">
  	</enum>
  </enums>
  <messages>
  	<message id='1' name="somename">
  	</message>
  	<message id="2" name="anothername">
  	</message>
  </messages>
</mavlink>

xml 結構主要可以分爲版本信息塊、enums包括的枚舉數據定義塊以及messages 消息定義塊。版本信息塊如下

<version>3</version>
<dialect>0</dialect>

enums 枚舉數據定義塊是<enums></enums> 標籤包括的內容,其中包括了很多通過<enum></enum>標籤定義的數據。
messages 消息定義塊是<messages></messages> 標籤包括的內容,其中包括了很多通過<message></message> 定義的數據。

對於<enum></enum><message></message>內部的具體結構在 mavschema.xsd 中有定義。這裏我們專注於 common.xml 的剖析,跳過mavschema.xsd 並不會影響我們對 common.xml 的理解。
下面分別分析 <enum></enum> 的結構和<message></message> 的結構。由於 <message></message> 包含了<enum></enum> 中的內容所以,這裏先分析<message></message>

2 message

這裏我們摘取名爲SYS_STATUS 的 message 進行分析

代碼塊 2

    <message id="1" name="SYS_STATUS">
      <description>The general system state. If the system is following the MAVLink standard, the system state is mainly defined by three orthogonal states/modes: The system mode, which is either LOCKED (motors shut down and locked), MANUAL (system under RC control), GUIDED (system with autonomous position control, position setpoint controlled manually) or AUTO (system guided by path/waypoint planner). The NAV_MODE defined the current flight state: LIFTOFF (often an open-loop maneuver), LANDING, WAYPOINTS or VECTOR. This represents the internal navigation state machine. The system status shows whether the system is currently active or not and if an emergency occurred. During the CRITICAL and EMERGENCY states the MAV is still considered to be active, but should start emergency procedures autonomously. After a failure occurred it should first move from active to critical to allow manual intervention and then move to emergency after a certain timeout.</description>
      <field type="uint32_t" name="onboard_control_sensors_present" enum="MAV_SYS_STATUS_SENSOR" display="bitmask" print_format="0x%04x">Bitmap showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present.</field>
      <field type="uint32_t" name="onboard_control_sensors_enabled" enum="MAV_SYS_STATUS_SENSOR" display="bitmask" print_format="0x%04x">Bitmap showing which onboard controllers and sensors are enabled:  Value of 0: not enabled. Value of 1: enabled.</field>
      <field type="uint32_t" name="onboard_control_sensors_health" enum="MAV_SYS_STATUS_SENSOR" display="bitmask" print_format="0x%04x">Bitmap showing which onboard controllers and sensors have an error (or are operational). Value of 0: error. Value of 1: healthy.</field>
      <field type="uint16_t" name="load" units="d%">Maximum usage in percent of the mainloop time. Values: [0-1000] - should always be below 1000</field>
      <field type="uint16_t" name="voltage_battery" units="mV">Battery voltage, UINT16_MAX: Voltage not sent by autopilot</field>
      <field type="int16_t" name="current_battery" units="cA">Battery current, -1: Current not sent by autopilot</field>
      <field type="int8_t" name="battery_remaining" units="%">Battery energy remaining, -1: Battery remaining energy not sent by autopilot</field>
      <field type="uint16_t" name="drop_rate_comm" units="c%">Communication drop rate, (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)</field>
      <field type="uint16_t" name="errors_comm">Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)</field>
      <field type="uint16_t" name="errors_count1">Autopilot-specific errors</field>
      <field type="uint16_t" name="errors_count2">Autopilot-specific errors</field>
      <field type="uint16_t" name="errors_count3">Autopilot-specific errors</field>
      <field type="uint16_t" name="errors_count4">Autopilot-specific errors</field>
    </message>

可以看到 message 的結構比較簡單,主要由<description> 段和<field> 組成。<description> 是對這個消息的描述,<field>是消息中所包含數據的每個域的具體說明,包含域的數據類型(type),域的數據名稱(name),及對該域數據的描述(嵌入在<field></field>標籤中的文本)。可以看到<field> 中還有enumdisplayprint_formatunits等其他屬性。enum屬性的內容即上面通過<enum></enum> 標籤定義的枚舉數據類型,例如onboard_control_sensors_present 中引用的名稱是MAV_SYS_STATUS_SENSOR 枚舉數據類型。display 定義這個域主要是用來顯示給用戶的,print_format 則指定了打印格式。這個message 實際上就是傳輸中的數據的具體結構,message中定義的每個field 在數據中一定存在,且大小按其type 域指定的數據類型相一致。

3 enum

下面來剖析enum 節點,這裏以上一節提到的MAV_SYS_STATUS_SENSOR爲例來說明。

代碼塊 3

<enum name="MAV_SYS_STATUS_SENSOR">
     <description>These encode the sensors whose status is sent as part of the SYS_STATUS message.</description>
     <entry value="1" name="MAV_SYS_STATUS_SENSOR_3D_GYRO">
       <description>0x01 3D gyro</description>
     </entry>
     <entry value="2" name="MAV_SYS_STATUS_SENSOR_3D_ACCEL">
       <description>0x02 3D accelerometer</description>
     </entry>
     <entry value="4" name="MAV_SYS_STATUS_SENSOR_3D_MAG">
       <description>0x04 3D magnetometer</description>
     </entry>
     <entry value="8" name="MAV_SYS_STATUS_SENSOR_ABSOLUTE_PRESSURE">
       <description>0x08 absolute pressure</description>
     </entry>
     <entry value="16" name="MAV_SYS_STATUS_SENSOR_DIFFERENTIAL_PRESSURE">
       <description>0x10 differential pressure</description>
     </entry>
     <entry value="32" name="MAV_SYS_STATUS_SENSOR_GPS">
       <description>0x20 GPS</description>
     </entry>
     <entry value="64" name="MAV_SYS_STATUS_SENSOR_OPTICAL_FLOW">
       <description>0x40 optical flow</description>
     </entry>
     <entry value="128" name="MAV_SYS_STATUS_SENSOR_VISION_POSITION">
       <description>0x80 computer vision position</description>
     </entry>
     <entry value="256" name="MAV_SYS_STATUS_SENSOR_LASER_POSITION">
       <description>0x100 laser based position</description>
     </entry>
     <entry value="512" name="MAV_SYS_STATUS_SENSOR_EXTERNAL_GROUND_TRUTH">
       <description>0x200 external ground truth (Vicon or Leica)</description>
     </entry>
     <entry value="1024" name="MAV_SYS_STATUS_SENSOR_ANGULAR_RATE_CONTROL">
       <description>0x400 3D angular rate control</description>
     </entry>
     <entry value="2048" name="MAV_SYS_STATUS_SENSOR_ATTITUDE_STABILIZATION">
       <description>0x800 attitude stabilization</description>
     </entry>
     <entry value="4096" name="MAV_SYS_STATUS_SENSOR_YAW_POSITION">
       <description>0x1000 yaw position</description>
     </entry>
     <entry value="8192" name="MAV_SYS_STATUS_SENSOR_Z_ALTITUDE_CONTROL">
       <description>0x2000 z/altitude control</description>
     </entry>
     <entry value="16384" name="MAV_SYS_STATUS_SENSOR_XY_POSITION_CONTROL">
       <description>0x4000 x/y position control</description>
     </entry>
     <entry value="32768" name="MAV_SYS_STATUS_SENSOR_MOTOR_OUTPUTS">
       <description>0x8000 motor outputs / control</description>
     </entry>
     <entry value="65536" name="MAV_SYS_STATUS_SENSOR_RC_RECEIVER">
       <description>0x10000 rc receiver</description>
     </entry>
     <entry value="131072" name="MAV_SYS_STATUS_SENSOR_3D_GYRO2">
       <description>0x20000 2nd 3D gyro</description>
     </entry>
     <entry value="262144" name="MAV_SYS_STATUS_SENSOR_3D_ACCEL2">
       <description>0x40000 2nd 3D accelerometer</description>
     </entry>
     <entry value="524288" name="MAV_SYS_STATUS_SENSOR_3D_MAG2">
       <description>0x80000 2nd 3D magnetometer</description>
     </entry>
     <entry value="1048576" name="MAV_SYS_STATUS_GEOFENCE">
       <description>0x100000 geofence</description>
     </entry>
     <entry value="2097152" name="MAV_SYS_STATUS_AHRS">
       <description>0x200000 AHRS subsystem health</description>
     </entry>
     <entry value="4194304" name="MAV_SYS_STATUS_TERRAIN">
       <description>0x400000 Terrain subsystem health</description>
     </entry>
     <entry value="8388608" name="MAV_SYS_STATUS_REVERSE_MOTOR">
       <description>0x800000 Motors are reversed</description>
     </entry>
     <entry value="16777216" name="MAV_SYS_STATUS_LOGGING">
       <description>0x1000000 Logging</description>
     </entry>
     <entry value="33554432" name="MAV_SYS_STATUS_SENSOR_BATTERY">
       <description>0x2000000 Battery</description>
     </entry>
     <entry value="67108864" name="MAV_SYS_STATUS_SENSOR_PROXIMITY">
       <description>0x4000000 Proximity</description>
     </entry>
     <entry value="134217728" name="MAV_SYS_STATUS_SENSOR_SATCOM">
       <description>0x8000000 Satellite Communication </description>
     </entry>
     <entry value="268435456" name="MAV_SYS_STATUS_PREARM_CHECK">
       <description>0x10000000 pre-arm check status. Always healthy when armed</description>
     </entry>
     <entry value="536870912" name="MAV_SYS_STATUS_OBSTACLE_AVOIDANCE">
       <description>0x20000000 Avoidance/collision prevention</description>
     </entry>
   </enum>

可以看出每個<enum></enum>中包括了很多的<entry></entry> ,每條<entry></entry>可以看作枚舉的一個值,value 屬性對應於值的具體大小,name 則可以看成是值的別名。
可以看出enum 類型不過是普通的數據型數據,那爲什麼要把這些數據類型單獨拿出來定義呢。一個原因是,每個值都有確定的含義,假想兩個系統之間進行通訊,雖然採用同樣的協議,但是如果對值的約定不一樣,這邊用1 代表四旋翼,那邊用1代表固定翼這樣顯然不匹配。另一個原因是,協議要自洽,儘量在協議文檔裏把協議的內容都包括進來,避免模糊和歧義。所以關於數值含義的約定也是協議的重要部分,單獨列出來可以讓協議結構更清晰明確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章