Disco Mavlink upload


#1

Product: [SkyController2 + Disco]
Product version: [1.0.7 + 1.7.1]
SDK version: [3.13.1]
Use of libARController: [YES]
SDK platform: [Android.]

Hi everyone. I have a problem with sending the mavlink file to the disco. I use the ARDataTransfer and everything looks good without any errors but when I invoke the sendMavlinkStart, the ARCOMMANDS_COMMON_FLIGHTPLANSTATE_COMPONENTSTATELISTCHANGED_COMPONENT_ENUM returns with ARCOMMANDS_COMMON_FLIGHTPLANSTATE_COMPONENTSTATELISTCHANGED_COMPONENT_MAVLINK_FILE.

I checked the mavlink file I generate and seems fine. I don’t know what the problem is since everything looks normal. Drone is calibrated with FreeFlight and has a GPS signal.

Here is a log I get everytime I invoke the sendMavlinkStart:
D/MAVLINK: STATE: Mavlink file is stopped (arg filepath and type are useless in this state) FILEPATH: /data/ftp/internal_000/flightplans/flightPlan.mavlink TYPE: Mavlink file for FlightPlan.

Does anyone know what I am doing wrong? Below is my FTP code:

try {
// FTP connection
ARDataTransferManager manager = new ARDataTransferManager();

        ARUtilsManager utilsManager = new ARUtilsManager();
        ARUTILS_ERROR_ENUM er = utilsManager.initFtp(SkyController2Activity.appContext2, currentDeviceService, ARUTILS_DESTINATION_ENUM.ARUTILS_DESTINATION_DRONE, ARUTILS_FTP_TYPE_ENUM.ARUTILS_FTP_TYPE_FLIGHTPLAN);

        Log.d("FTP", "initFtp returns: " + er.toString());

        ARDataTransferUploader uploadManager = manager.getARDataTransferUploader();

        uploadManager.createUploader(utilsManager, droneFilePath, filepath , this, this, this, this, ARDATATRANSFER_UPLOADER_RESUME_ENUM.ARDATATRANSFER_UPLOADER_RESUME_FALSE);

        Runnable uploader = uploadManager.getUploaderRunnable();

        Thread uploaderThread = new Thread(uploader);
        uploaderThread.start();

        try { uploaderThread.join(); } catch (InterruptedException e) { Log.d("DBG", "join " + e.toString());  }

        uploadManager.dispose();
        manager.dispose();
        utilsManager.closeFtp(SkyController2Activity.appContext2, currentDeviceService);
        utilsManager.dispose();
    }
    catch (Exception e)
    {
        Log.d("DBG", "FlightPlanTransfer " + e.toString());
    }
    catch (Throwable e)
    {
        Log.d("DBG", "FlightPlanTransfer " + e.toString());
    }

#2

OK. I narrowed down my problem to the generated mavlink file. I generate the file using libARMavlink in java. When I try to play the file I generated I get the ARCOMMANDS_COMMON_FLIGHTPLANSTATE_COMPONENTSTATELISTCHANGED_COMPONENT_MAVLINK_FILE. But when I use a sample file I found online it works fine.
I will just post my code of the mavlink generation hoping someone can help me figure this out.
Thanks :slight_smile:

private ARMavlinkMissionItem item;
private ARMavlinkMissionItem item2;
private ARMavlinkMissionItemList list;
private ARMavlinkFileGenerator generator;
private String filepath= Environment.getExternalStorageDirectory().getPath() + "/parrot/flightPlan3.mavlink";

public String parseItem(Context context, ARDiscoveryDeviceService currentDeviceService){
try {
generator = new ARMavlinkFileGenerator();
item = ARMavlinkMissionItem.CreateMavlinkNavWaypointMissionItem((float) 48.523519, (float) 2.221903,50,0);
generator.addMissionItem(item);
item2 = ARMavlinkMissionItem.CreateMavlinkNavWaypointMissionItem((float) 50.01, (float) 2.5,50,0);
generator.addMissionItem(item2);
item.dispose();
item2.dispose();
return “ALL OK”;
}catch (ARMavlinkException e){
return e.toString();
}
}


#3

I had a similar issue at first and tracked it down to a couple mission items that the Disco diea not like.

I’ll see about sharing once I’m at my computer.


#4

Hey @synman,
Thanks for your reply. I have finally figured this out. It seems that the disco doesnot like flightplans that do not have a land waypoint at the end. Everything works great now. :smile:


#5

I bypassed POIs (ROIs?)

        // initial pass to build POIs - bypass if evinrude
        if (!evinrude) {
            for (MavlinkMarker marker : ARPro3Application.mavlinkMarkers.getPois()) {
                final ARMavlinkMissionItem roi = ARMavlinkMissionItem.CreateMavlinkSetROI(MAV_ROI.MAV_ROI_LOCATION, 0, marker.getId(), (float) marker.getLatitude(), (float) marker.getLongitude(), (float) marker.getAltitude());
                generator.addMissionItem(roi);
            }
        }

And bypassed speed:

            if (lastSpeed != marker.getSpeed() && !evinrude) {
                final ARMavlinkMissionItem speed = ARMavlinkMissionItem.CreateMavlinkChangeSpeedMissionItem(0, marker.getSpeed(), -1);
                generator.addMissionItem(speed);

                lastSpeed = marker.getSpeed();
            }

and any waypoint references to POIs:

            // create our POI reference if we need one
            if (!evinrude && mark.getPoi() != null && !mark.getPoi().equals(activePoi)) {
                final ARMavlinkMissionItem view = ARMavlinkMissionItem.CreateMavlinkSetViewMode(MAV_VIEW_MODE_TYPE.VIEW_MODE_TYPE_ROI, mark.getPoi().getId());
                generator.addMissionItem(view);

                activePoi = mark.getPoi();

                absoluteActive = false;
                progressiveActive = false;
            }

I also avoid progressive and non progressive views (I just let the evinrude do whatever it’s default is (absolute likely):

                        final ARMavlinkMissionItem view = ARMavlinkMissionItem.CreateMavlinkSetViewMode(MAV_VIEW_MODE_TYPE.VIEW_MODE_TYPE_CONTINUE, -1);
                        generator.addMissionItem(view);

                        final ARMavlinkMissionItem view = ARMavlinkMissionItem.CreateMavlinkSetViewMode(MAV_VIEW_MODE_TYPE.VIEW_MODE_TYPE_ABSOLUTE, -1);
                        generator.addMissionItem(view);

Additionally, contrary to your approach, I only include land if directed to (in my testing it is NOT required):

            // we want to land before delay
            if (marker.getAction() != null && marker.getAction() == MavlinkMarkerAction.LAND) {
                final ARMavlinkMissionItem land = ARMavlinkMissionItem.CreateMavlinkLandMissionItem((float) marker.getLatitude(), (float) marker.getLongitude(), (float) marker.getAltitude(), (float) yaw);
                generator.addMissionItem(land);
         ......

#6

Hi synman,

Thanks for your reply. This info is very appreciated. I have one more question. For some reason, the disco wants to elevate to a height of 50m at the first and last waypoint and want to perform a single turn loiter at the first waypoint as well. Did you have any similar problems with your implementation? Thanks in advance.


#7

Looks like the disco has the 50meters as a preset for the first waypoint and cannot be changed as I understand. That is also the case with the loiter on the first waypoint as well. At least that what it does on the official application as well so I didn’t mess with it any more but just accepted it. I hope this info helps other people as well…