0

我正在开发一个使用 MAVLINK 协议进行通信的应用程序。我为此目的使用dronefleet 。我的应用程序有一个服务,它运行ReadThread检查传入的MAVLINK 消息的类型。ReadThread然后向 UI 发送消息以更新一些TextViews无人机的信息,如电池状态等。这是我的代码。

ReadThreadDService.java中

import io.dronefleet.mavlink.MavlinkMessage;
import io.dronefleet.mavlink.common.Attitude;
import io.dronefleet.mavlink.common.SysStatus;

public static final int ATTITUDE = 1;
public static final int SYS_STATUS = 2;

private class ReadThread extends Thread {
        private AtomicBoolean keep = new AtomicBoolean(true);
        @Override
        public void run() {
            while(keep.get()){
                if(inputStream == null)
                    return;
                MavlinkMessage message;
                try {
---------------------get MAVLINK message from stream here---------------
                    message = mavlinkConnection.next();
    
-------------------check MAVLINK message type and then send message to UI for updating related fields--------------------
           
                    if(message.getPayload() instanceof Attitude) {
                        MavlinkMessage<Attitude> attitudeMessage = (MavlinkMessage<Attitude>)message;

                        myHandler.obtainMessage(ATTITUDE, attitudeMessage).sendToTarget();
                    }

----------------removing comments causes app to crash---------------------
                    
/*if(message.getPayload() instanceof SysStatus) {
                        MavlinkMessage<SysStatus> sysStatusMessage = (MavlinkMessage<SysStatus>)message;
                        int battery = sysStatusMessage.getPayload().batteryRemaining();
                        
                        myHandler.obtainMessage(SYS_STATUS, Integer.toString(battery)).sendToTarget();*/
                    }
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        public void setKeep(boolean keep) {
            this.keep.set(keep);
        }
    }

handleMessage()MainActivity.java

            switch (msg.what) {
                
                case DService.SYS_STATUS:
                    String battery = (String) msg.obj + "%";
                    myActivity.get().batteryView.setText(battery);

                case DService.ATTITUDE:
                    MavlinkMessage<Attitude> message = (MavlinkMessage<Attitude>) msg.obj;
                    String pitch = Float.toString(message.getPayload().pitch());
                    String roll = Float.toString(message.getPayload().roll());
                    String yaw = Float.toString(message.getPayload().yaw());
                    myActivity.get().pitchView.setText(pitch);
                    myActivity.get().rollView.setText(roll);
                    myActivity.get().yawView.setText(yaw);
                    break;
        
            }
        }

我的问题是,如果我在我的ReadThread. 如果我检查(比如说)SYS_STATUSATTITUDE,那么 UI 中的相应TextViewss 每秒都会无缝更新(这是 MAVLINK 发送消息的速率)。但不适用于 2 个消息类。如果我从一个if区块中删除评论,我的应用程序就会崩溃。

可能是什么原因?我handleMessage()错了吗?我需要使用MessageQueue或其他一些android机制吗?我应该ReadThread为每个 MAVLINK 消息类型运行单独的线程吗?

我正在 Ubuntu 18 上开发,并使用 Android Studio。

4

1 回答 1

0

logcat 在崩溃之前是否有任何异常被您的程序抛出?

我不会为每个 MAVLink 消息类型的句柄消息使用多个线程,因为我猜测 MAVLink 连接的dronefleet 解析器是有状态的(MAVLink 使用魔术前缀和有效负载长度来分隔数据包)并且它可能会中断或几乎同步,如果从多个线程调用。

如果您担心您可能过于频繁地发送更新,您可以让读取线程存储来自不同 MAVLink 消息的值,并且一个单独的线程根据每条消息的最新值或集合以固定间隔发送更新自上次更新以来收到的消息数。

于 2022-02-08T03:44:07.137 回答