0

I am developing an app that communicates using the MAVLINK protocol. I am using dronefleet for this purpose. My app has a service which runs a ReadThread that checks the incoming MAVLINK messages for their type. ReadThread then sends messages to the UI for updating some TextViews with the drone's information like battery status, etc. Here is my code.

ReadThread in DService.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() in 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;
        
            }
        }

My problem is my app is crashing if I am checking for more than one type of MAVLINK message in my ReadThread. If I check for (say) either SYS_STATUS or ATTITUDE, then the corresponding TextViewss in the UI are getting updated seamlessly every second (which is the rate of messages sent by MAVLINK). But not for 2 message classes. If I remove comments from one if block, my app crashes.

Whats could be the reason? Is my handleMessage() wrong? Do I need to use MessageQueue or some other android mechanism? Should I run separate threads like ReadThread for each MAVLINK message type?

I am developing on Ubuntu 18, and using Android Studio.

Nancy
  • 315
  • 1
  • 5
  • 16

1 Answers1

0

Does logcat have any exceptions being thrown by your program before it crashes?

I would not use multiple threads for each MAVLink message type's handlemessage because I'm guessing the dronefleet parser for the MAVLink connection is stateful (MAVLink uses a magic prefix and payload length to delimit packets) and it would probably either break or be nearly synchronous if called from multiple threads.

If you're worried that you might be sending updates too frequently you could have the read thread store the values from the different MAVLink messages and a separate thread send updates at a fixed interval based on either the latest value for each message or on the set of messages received since the last update.

B T
  • 1