【无人机学习之DroidPlanner】msg_sys_status系统状态

█ 【无人机学习之DroidPlanner】msg_sys_status系统状态


█ 系列文章目录

提示:这里是收集了无人机的相关文章


█ 文章目录


█ 读前说明

  • 本文通过学习别人写demo,学习一些课件,参考一些博客,学习相关知识,如有涉及侵权请告知
  • 本文可能只简单罗列了一些相关的代码实现过程,复制了一些大神的高论,如内容有误请自行辨别
  • 涉及到的逻辑以及说明可能只做了简单的介绍,主要当做笔记,了解过程而已,如有不同看法,欢迎下方评论
  • 本文源码:https://github.com/DroidPlanner/Tower


█ 系统状态的消息格式

1.MAVLink协议简介

此内容在【无人机学习之DroidPlanner】msg_heartbeat心跳包文中介绍过,在此不做描述

2.官网的描述

在这里插入图片描述
在这里插入图片描述

3.系统状态的消息格式

在系统状态的消息类msg_sys_status.java中可以看出msgid=1,因此当收到msgid=1即可找到msg_sys_status通过unpack将 payload 转换成msg_heartbeat对象

##  2.com.xml

```java
<mavlink>
     <version>3</version>
     <dialect>0</dialect>
     <enums>。。。。。。</enums>
     <messages>
          <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>
          。。。。。。
     </messages>
</mavlink>

在这里插入图片描述
在这里插入图片描述

4.msg_sys_status.java源代码

此文件在Mavlink\src\com\MAVLink\common\msg_sys_status.java中

/**
* 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.
*/
public class msg_sys_status extends MAVLinkMessage{

    public static final int MAVLINK_MSG_ID_SYS_STATUS = 1;
    public static final int MAVLINK_MSG_LENGTH = 31;
    private static final long serialVersionUID = MAVLINK_MSG_ID_SYS_STATUS;


      
    /**
    * Bitmap showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present.
    */
    public long onboard_control_sensors_present;
      
    /**
    * Bitmap showing which onboard controllers and sensors are enabled:  Value of 0: not enabled. Value of 1: enabled.
    */
    public long onboard_control_sensors_enabled;
      
    /**
    * Bitmap showing which onboard controllers and sensors have an error (or are operational). Value of 0: error. Value of 1: healthy.
    */
    public long onboard_control_sensors_health;
      
    /**
    * Maximum usage in percent of the mainloop time. Values: [0-1000] - should always be below 1000
    */
    public int load;
      
    /**
    * Battery voltage, UINT16_MAX: Voltage not sent by autopilot
    */
    public int voltage_battery;
      
    /**
    * Battery current, -1: Current not sent by autopilot
    */
    public short current_battery;
      
    /**
    * Communication drop rate, (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
    */
    public int drop_rate_comm;
      
    /**
    * Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
    */
    public int errors_comm;
      
    /**
    * Autopilot-specific errors
    */
    public int errors_count1;
      
    /**
    * Autopilot-specific errors
    */
    public int errors_count2;
      
    /**
    * Autopilot-specific errors
    */
    public int errors_count3;
      
    /**
    * Autopilot-specific errors
    */
    public int errors_count4;
      
    /**
    * Battery energy remaining, -1: Battery remaining energy not sent by autopilot
    */
    public byte battery_remaining;
    

    /**
    * 为这种类型的消息生成mavlink消息的有效负载,组包数据
    * Generates the payload for a mavlink message for a message of this type
    * @return
    */
    public MAVLinkPacket pack(){
        MAVLinkPacket packet = new MAVLinkPacket(MAVLINK_MSG_LENGTH);
        packet.sysid = 255;
        packet.compid = 190;
        packet.msgid = MAVLINK_MSG_ID_SYS_STATUS;
              
        packet.payload.putUnsignedInt(onboard_control_sensors_present);
              
        packet.payload.putUnsignedInt(onboard_control_sensors_enabled);
              
        packet.payload.putUnsignedInt(onboard_control_sensors_health);
              
        packet.payload.putUnsignedShort(load);
              
        packet.payload.putUnsignedShort(voltage_battery);
              
        packet.payload.putShort(current_battery);
              
        packet.payload.putUnsignedShort(drop_rate_comm);
              
        packet.payload.putUnsignedShort(errors_comm);
              
        packet.payload.putUnsignedShort(errors_count1);
              
        packet.payload.putUnsignedShort(errors_count2);
              
        packet.payload.putUnsignedShort(errors_count3);
              
        packet.payload.putUnsignedShort(errors_count4);
              
        packet.payload.putByte(battery_remaining);
        
        return packet;
    }

    /**
    * 将系统状态信息解码到该类字段中
    * Decode a sys_status message into this class fields
    *
    * @param payload The message to decode
    */
    public void unpack(MAVLinkPayload payload) {
        payload.resetIndex();
              
        this.onboard_control_sensors_present = payload.getUnsignedInt();
              
        this.onboard_control_sensors_enabled = payload.getUnsignedInt();
              
        this.onboard_control_sensors_health = payload.getUnsignedInt();
              
        this.load = payload.getUnsignedShort();
              
        this.voltage_battery = payload.getUnsignedShort();
              
        this.current_battery = payload.getShort();
              
        this.drop_rate_comm = payload.getUnsignedShort();
              
        this.errors_comm = payload.getUnsignedShort();
              
        this.errors_count1 = payload.getUnsignedShort();
              
        this.errors_count2 = payload.getUnsignedShort();
              
        this.errors_count3 = payload.getUnsignedShort();
              
        this.errors_count4 = payload.getUnsignedShort();
              
        this.battery_remaining = payload.getByte();
        
    }

    /**
    * 构造函数,只需初始化msgid
    * Constructor for a new message, just initializes the msgid
    */
    public msg_sys_status(){
        msgid = MAVLINK_MSG_ID_SYS_STATUS;
    }

    /**
    * 构造函数,用有效负载初始化消息,从mavlink数据包
    * Constructor for a new message, initializes the message with the payload
    * from a mavlink packet
    *
    */
    public msg_sys_status(MAVLinkPacket mavLinkPacket){
        this.sysid = mavLinkPacket.sysid;
        this.compid = mavLinkPacket.compid;
        this.msgid = MAVLINK_MSG_ID_SYS_STATUS;
        unpack(mavLinkPacket.payload);        
    }
}
    

5.大致过程

通过硬件接口(USB/蓝牙等)读取消息,通过msgid判断是msg_sys_status类型,再通过msg_sys_status自带的unpack方法解码MAVLinkPayload 信息成msg_sys_status对象

6.电池电量

本文主要讲下msg_sys_status下的电池电量battery_remaining的走向流程,这是一个百分比,电池电量满时,返回100,即电池100%。

    /**
    * Battery energy remaining, -1: Battery remaining energy not sent by autopilot
    */
    public byte battery_remaining;

█ 读取数据

1.流程

  • App和飞控连接上
  • MavLinkDroneManager.java中创建MAVLinkClient对象,并将设置了MAVLinkClient收到消息后的回调(监听)
  • MAVLinkClient.java中创建AndroidMavLinkConnection对象 mavlinkConn
  • 通过 mavlinkConn.addMavLinkConnectionListener(tag, mConnectionListener);绑定MavLinkConnectionListener mConnectionListener事件来监听自飞控的反馈数据(监听收到的数据)
  • 收到数据后执行listener.notifyReceivedData(packet);(传到MavLinkDroneManager中处理)来向外传播数据
执行过程说明
MAVLinkClient.java是MavLinkDroneManager中的一个对象
MavLinkDroneManager.java创建了ArduCopter对象,它的父类是 ArduPilot
ArduPilot.java它的父类是 GenericMavLinkDrone
GenericMavLinkDrone.javaMavLinkDroneManager.java

2.MAVLinkClient.java

提示:此文件全路径为:org.droidplanner.services.android.impl.communication.service.MAVLinkClient.java

public class MAVLinkClient implements DataLink.DataLinkProvider<MAVLinkMessage> {

    private static final int DEFAULT_SYS_ID = 255;
    private static final int DEFAULT_COMP_ID = 190;

    /**
     * Maximum possible sequence number for a packet.
     */
    private static final int MAX_PACKET_SEQUENCE = 255;
    private final DataLink.DataLinkListener<MAVLinkPacket> listener;// 下一步需要查看的信息
    private final MavLinkConnectionListener mConnectionListener = new MavLinkConnectionListener() {

        @Override
        public void onReceivePacket(final MAVLinkPacket packet) {
        	Log.e("## "+getClass().getName(), "1.  MavLinkConnectionListener.onReceivePacket():"+packet);
            listener.notifyReceivedData(packet);// 下一步需要查看的信息
        }

        @Override
        public void onConnectionStatus(final LinkConnectionStatus connectionStatus) {
            listener.onConnectionStatus(connectionStatus);

            switch (connectionStatus.getStatusCode()) {
                case LinkConnectionStatus.DISCONNECTED:
                    closeConnection();
                    break;
            }
        }
    };
    
    public MAVLinkClient(Context context, DataLink.DataLinkListener<MAVLinkPacket> listener,
                         ConnectionParameter connParams, DroneCommandTracker commandTracker) {
        this.context = context;
        this.listener = listener;// 下一步需要查看的信息,是在MavLinkDroneManager中创建的

        if(connParams == null){
            throw new NullPointerException("Invalid connection parameter argument.");
        }

        this.connParams = connParams;
        this.commandTracker = commandTracker;
    }
    /**
     * Setup a MAVLink connection based on the connection parameters.
     */
    @Override
    public synchronized void openConnection() {
        。。。。。。
        Log.e("## "+getClass().getName(), "0.  mavlinkConn.addMavLinkConnectionListener(tag, mConnectionListener);绑定最早接收mavlink信息监听事件");
        mavlinkConn.addMavLinkConnectionListener(tag, mConnectionListener);
        if (mavlinkConn.getConnectionStatus() == MavLinkConnection.MAVLINK_DISCONNECTED) {
            mavlinkConn.connect(null);
        }
    }
    。。。。。。
}    

3.MavLinkDroneManager.java

提示:此文件全路径为:org.droidplanner.services.android.impl.core.drone.manager.MavLinkDroneManager.java

    public class MavLinkDroneManager extends DroneManager<MavLinkDrone, MAVLinkPacket> implements MagnetometerCalibrationImpl.OnMagnetometerCalibrationListener {

    private static final int DEFAULT_STREAM_RATE = 2; //Hz

    @Override
    public void notifyReceivedData(MAVLinkPacket packet) {
        MAVLinkMessage receivedMsg = packet.unpack();
        if (receivedMsg == null)
            return;
          Log.e("## "+getClass().getName(), "2. notifyReceivedData:" + receivedMsg.toString());
//        Log.e("notifyReceivedData",receivedMsg.toString());
        if (receivedMsg.msgid == msg_statustext.MAVLINK_MSG_ID_STATUSTEXT) {
            msg_statustext statustext = (msg_statustext) receivedMsg;
            saveVersion(statustext);
        }
        if (receivedMsg.msgid == msg_command_ack.MAVLINK_MSG_ID_COMMAND_ACK) {
            msg_command_ack commandAck = (msg_command_ack) receivedMsg;
            handleCommandAck(commandAck);
        } else {
            Log.e("## "+getClass().getName(), "3.  mavLinkMsgHandler.receiveData(receivedMsg)");
            this.mavLinkMsgHandler.receiveData(receivedMsg);// 这边处理的是心跳包,同时绑定对外广播的事件
            if (this.drone != null) {
                Log.e("## "+getClass().getName(), "4.  drone.onMavLinkMessageReceived(receivedMsg)");
                this.drone.onMavLinkMessageReceived(receivedMsg);// 下一步需要查看的信息 ArduCopter.java的父类ArduPilot.java
            }
        }

        if (!connectedApps.isEmpty()) {
            for (DroneApi droneEventsListener : connectedApps.values()) {
            	// 虽然执行到,但是mavlinkObserversList.isEmpty()直接跳出所以相当于没执行,可能需要其他触发条件吧
                Log.e("## "+getClass().getName(), "5.  droneEventsListener.onReceivedMavLinkMessage(receivedMsg)");
                droneEventsListener.onReceivedMavLinkMessage(receivedMsg);
            }
        }
    }
	。。。。。。

4.ArduPilot.java

提示:此文件全路径为:org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduPilot.java

/**
 * Base class for the ArduPilot autopilots
 */
public abstract class ArduPilot extends GenericMavLinkDrone {
    public static final int AUTOPILOT_COMPONENT_ID = 1;
    public static final int ARTOO_COMPONENT_ID = 0;
    public static final int TELEMETRY_RADIO_COMPONENT_ID = 68;


    @Override
    public void onMavLinkMessageReceived(MAVLinkMessage message) {
//        if (message.sysid != this.getSysid()) {
//            // Reject Messages that are not for the system id
//            return;
//        }
        // ### mavlink解析到的数据和UI获取数据建立联系
        Log.e("## " + getClass().getName(), "a1. ArduPilot.java - onMavLinkMessageReceived:" + message.toString());

        int compId = message.compid;
        if (compId != AUTOPILOT_COMPONENT_ID
                && compId != ARTOO_COMPONENT_ID
                && compId != TELEMETRY_RADIO_COMPONENT_ID) {
            return;
        }

        if (!getParameterManager().processMessage(message)) {

            getWaypointManager().processMessage(message);
            getCalibrationSetup().processMessage(message);

            switch (message.msgid) {
                //msg-id=253  文本信息
                case msg_statustext.MAVLINK_MSG_ID_STATUSTEXT:
                    // These are any warnings sent from APM:Copter with
                    // gcs_send_text_P()
                    // This includes important thing like arm fails, prearm fails, low
                    // battery, etc.
                    // also less important things like "erasing logs" and
                    // "calibrating barometer"
                    msg_statustext msg_statustext = (msg_statustext) message;
                    processStatusText(msg_statustext);
                    break;
                。。。。。。

                default:
                    break;
            }
        }
        // 下一步需要查看的信息
        // 这边没有处理的消息类型,传到父类GenericMavLinkDrone.java中处理
        Log.e("## " + getClass().getName(), "a2. ArduPilot.java - 调用父类的实现:" + message.sysid);
        super.onMavLinkMessageReceived(message);
    }
}

5.GenericMavLinkDrone .java

提示:此文件全路径为:org.droidplanner.services.android.impl.core.drone.autopilot.apm.GenericMavLinkDrone.java

/**
 * Base drone implementation.
 * Supports mavlink messages belonging to the common set: https://pixhawk.ethz.ch/mavlink/
 * <p/>
 * Created by Fredia Huya-Kouadio on 9/10/15.
 */
public class GenericMavLinkDrone implements MavLinkDrone {

    private final DataLink.DataLinkProvider<MAVLinkMessage> mavClient;
    private final DroneEvents events;
    private String droneId;
    protected final Battery battery = new Battery();


    public GenericMavLinkDrone(String droneId, Context context, Handler handler, DataLink.DataLinkProvider<MAVLinkMessage> mavClient,
                               AutopilotWarningParser warningParser, LogMessageListener logListener) {
        this.droneId = droneId;
        this.mavClient = mavClient;
        events = new DroneEvents(this);
    }

    @Override
    public void notifyDroneEvent(DroneInterfaces.DroneEventsType event) {
        switch (event) {
            case DISCONNECTED:
                signal.setValid(false);
                break;
        }

        events.notifyDroneEvent(event);// 下一步需要查看的信息 如何将消息向外广播出去
    }
    
    @Override
    public void onMavLinkMessageReceived(MAVLinkMessage message) {

//        if (message.sysid != this.getSysid()) {
//            // Reject Messages that are not for the system id
//            return;
//        }
        // ### mavlink解析到的数据和UI获取数据建立联系
        Log.e("## "+getClass().getName(), "a3. GenericMavLinkDrone.java - onMavLinkMessageReceived:" + message);
        //处理心跳信息
        onHeartbeat(message);

        switch (message.msgid) {
            //msg-id=0 心跳信息
            case msg_heartbeat.MAVLINK_MSG_ID_HEARTBEAT:
                msg_heartbeat msg_heart = (msg_heartbeat) message;
                processHeartbeat(msg_heart);
                break;
            //msg-id=1 系统状态
            case msg_sys_status.MAVLINK_MSG_ID_SYS_STATUS:
                msg_sys_status m_sys = (msg_sys_status) message;
                processSysStatus(m_sys);
                break;
            。。。。。。
        }
    }

    protected void processSysStatus(msg_sys_status m_sys) {
        Log.e("## "+getClass().getName(), "a4. GenericMavLinkDrone.java - processSysStatus "+m_sys.toString());
        processBatteryUpdate(m_sys.voltage_battery / 1000.0, m_sys.battery_remaining,
            m_sys.current_battery / 100.0);
    }
    
    protected void processBatteryUpdate(double voltage, double remain, double current) {
        Log.e("## "+getClass().getName(), "a5. GenericMavLinkDrone.java - processBatteryUpdate ");
        if (battery.getBatteryVoltage() != voltage || battery.getBatteryRemain() != remain || battery.getBatteryCurrent() != current) {
            battery.setBatteryVoltage(voltage);
            battery.setBatteryRemain(remain);
            battery.setBatteryCurrent(current);
            Log.e("## "+getClass().getName(), "a6. GenericMavLinkDrone.java - 通知无人机事件 notifyDroneEvent(DroneEvents) :DroneEventsType.BATTERY");
            notifyDroneEvent(DroneInterfaces.DroneEventsType.BATTERY);
        }
    }
}

6.DroneApi.java

提示:此文件全路径为:org.droidplanner.services.android.impl.api.DroneApi.java
在【3.MavLinkDroneManager.java】中执行droneEventsListener.onReceivedMavLinkMessage(receivedMsg);后的下一句

/**
 * Implementation for the IDroneApi interface.
 */
public final class DroneApi extends IDroneApi.Stub implements DroneInterfaces.OnDroneListener, DroneInterfaces.AttributeEventListener,
    DroneInterfaces.OnParameterManagerListener, MagnetometerCalibrationImpl.OnMagnetometerCalibrationListener, IBinder.DeathRecipient {

    //The Reset ROI mission item was introduced in version 2.6.8. Any client library older than this do not support it.
    private final static int RESET_ROI_LIB_VERSION = 206080;

    public void onReceivedMavLinkMessage(MAVLinkMessage msg) {
        if (mavlinkObserversList.isEmpty()) {
            Log.e("## "+getClass().getName(), "c0.  onReceivedMavLinkMessage mavlinkObserversList.isEmpty()");
            return;// 在这边就退出来了
        }
        Log.e("## "+getClass().getName(), "c1.  onReceivedMavLinkMessage");
        if (msg != null) {
            MavlinkMessageWrapper msgWrapper = new MavlinkMessageWrapper(msg);
            for (IMavlinkObserver observer : mavlinkObserversList) {
                try {
                    Log.e("## "+getClass().getName(), "c2.  observer.onMavlinkMessageReceived(msgWrapper)");
                    observer.onMavlinkMessageReceived(msgWrapper);
                } catch (RemoteException e) {
                    Timber.e(e, e.getMessage());
                    try {
                        removeMavlinkObserver(observer);
                    } catch (RemoteException e1) {
                        Timber.e(e1, e1.getMessage());
                    }
                }
            }
        }
    }
}

7.运行结果

E/## org.droidplanner.services.android.impl.communication.service.MAVLinkClient$1: 1.  MavLinkConnectionListener.onReceivePacket():com.MAVLink.MAVLinkPacket@efcde3c
E/## org.droidplanner.services.android.impl.core.drone.manager.MavLinkDroneManager: 2. notifyReceivedData:MAVLINK_MSG_ID_SYS_STATUS - sysid:1 compid:1 onboard_control_sensors_present:325188623 onboard_control_sensors_enabled:308395023 onboard_control_sensors_health:57777163 load:371 voltage_battery:12389 current_battery:-1884 drop_rate_comm:0 errors_comm:0 errors_count1:0 errors_count2:0 errors_count3:0 errors_count4:0 battery_remaining:100
E/## org.droidplanner.services.android.impl.core.drone.manager.MavLinkDroneManager: 3.  mavLinkMsgHandler.receiveData(receivedMsg)
E/## org.droidplanner.services.android.impl.core.drone.manager.MavLinkDroneManager: 4.  drone.onMavLinkMessageReceived(receivedMsg)

E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a1. ArduPilot.java - onMavLinkMessageReceived:MAVLINK_MSG_ID_SYS_STATUS - sysid:1 compid:1 onboard_control_sensors_present:325188623 onboard_control_sensors_enabled:308395023 onboard_control_sensors_health:57777163 load:371 voltage_battery:12389 current_battery:-1884 drop_rate_comm:0 errors_comm:0 errors_count1:0 errors_count2:0 errors_count3:0 errors_count4:0 battery_remaining:100
E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a2. ArduPilot.java - 调用父类的实现:1
E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a3. GenericMavLinkDrone.java - onMavLinkMessageReceived:MAVLINK_MSG_ID_SYS_STATUS - sysid:1 compid:1 onboard_control_sensors_present:325188623 onboard_control_sensors_enabled:308395023 onboard_control_sensors_health:57777163 load:371 voltage_battery:12389 current_battery:-1884 drop_rate_comm:0 errors_comm:0 errors_count1:0 errors_count2:0 errors_count3:0 errors_count4:0 battery_remaining:100
E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a4. GenericMavLinkDrone.java - processSysStatus MAVLINK_MSG_ID_SYS_STATUS - sysid:1 compid:1 onboard_control_sensors_present:325188623 onboard_control_sensors_enabled:308395023 onboard_control_sensors_health:57777163 load:371 voltage_battery:12389 current_battery:-1884 drop_rate_comm:0 errors_comm:0 errors_count1:0 errors_count2:0 errors_count3:0 errors_count4:0 battery_remaining:100
E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a5. GenericMavLinkDrone.java - processBatteryUpdate 
E/## org.droidplanner.services.android.impl.core.drone.autopilot.apm.ArduCopter: a6. GenericMavLinkDrone.java - 通知无人机事件 notifyDroneEvent(DroneEvents) :DroneEventsType.BATTERY

E/## org.droidplanner.services.android.impl.core.drone.manager.MavLinkDroneManager: 5.  droneEventsListener.onReceivedMavLinkMessage(receivedMsg)
E/## org.droidplanner.services.android.impl.api.DroneApi: c0.  onReceivedMavLinkMessage

在这里插入图片描述

█ 广播数据

█ 接收数据

█ 相关资料

提示:这里是参考的相关文章

  1. ardupilot 如何为android 增加mavlink协议_陌城烟雨-CSDN博客
  2. 打造自己的HelloDrone 无人机APP过程《2》_陌城烟雨-CSDN博客_drone无人机怎么下app
  3. Mavlink协议理解Pixhawk APM(一)_super_mice的专栏-CSDN博客
  4. Mavlink 消息简介 - pixhawk

█ 免责声明

博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持!

提示:转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/112844372

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值