凸多邊形航線規劃算法優化

本文是對參考文章《無人機航線規劃思路剖析,基於凸多邊形地塊往復式運動》算法實現的一個優化,優化內容點:

  1. 航線間隔的優化
  2. 航線外擴

注:接下來的內容,請務必掌握參考文章內容的知識點。

航線間隔計算的優化

優化前寫法:

作者使用了一個非常簡單粗暴的寫法,即用多邊形外接矩形計算出最北方向和最南方向的距離,然後除以航線間隔距離,得出規劃航線的數量:

function distance(p1,p2){
  /**leaflet提供的方法*/
  return L.latLng(p1.lat,p1.lng).distanceTo(L.latLng(p2.lat,p2.lng))
}

/** nw到sw的距離*/
var dist = distance(nw,sw);

/** 得出答案*/
var lines = parseInt(dist / 20)

然後再用最北方向的緯度減去最南方向的緯度,除以已知的航線數量,即可得到每條航線之間的緯度差,以此從上往下計算出每條航線的緯度:

var N=[];
var stepLat=(nw.lat-sw.lat)/lines;
for(var i=0;i<lines;i++){
  N.push(nw.lat - i * stepLat)
}

我們可以舉個簡單的例子來表明此方法的弊端,假設北緯與南緯之間的間隔距離爲 100 米,並且要求航線間隔是 30 米,按照上述代碼可計算出 lines = 3,然後再計算出緯度差畫出航線,我們所期望的間隔 30 米,在此平均算法後,實際的每條間隔卻變成了 33.33 米,如圖:
image.png
導致了旁向重疊率一直不準確。

優化後寫法

使用方位角算法:已知一點經緯度,方位角,距離,求另一點經緯度。

 public static MapLatLng getBearingLatLng(MapLatLng latLng, int distance, double bearing) {
        double R = 6371.393 * 1000;

        double δ = distance / R;
        double θ = toRadius(bearing);

        double φ1 = toRadius(latLng.getLatitude());
        double λ1 = toRadius(latLng.getLongitude());

        double sinφ2 = Math.sin(φ1) * Math.cos(δ) + Math.cos(φ1) * Math.sin(δ) * Math.cos(θ);
        double φ2 = Math.asin(sinφ2);

        double y = Math.sin(θ) * Math.sin(δ) * Math.cos(φ1);
        double x = Math.cos(δ) - Math.sin(φ1) * sinφ2;
        double λ2 = λ1 + Math.atan2(y, x);

        double lat = toDegree(φ2);
        double lng = toDegree(λ2);

        return new MapLatLng(lat, lng);
    }

  	private static double toRadius(double value) {
        return value * Math.PI / 180;
    }

    private static double toDegree(double value) {
        return value * 180 / Math.PI;
    }

具體實現是,以最北緯度爲基準點,在航線間隔距離下,計算出 180 度方向(正北爲0度)的一個點,該點則是第一條航線上的點,然後再通過該點爲基準點,一直反覆計算出下一個點,直到下一個航點的位置小於最南緯度爲止,仍是上述的例子,計算後的航線效果如圖:
image.png

航線外擴

航線外擴功能主要是爲了無人機能更好的拍攝地塊邊界,在合成三維模型中有更好的展現。在參考文章中,作者並未對航線的外擴進行實現,我們在分析競品時,可以看見 DJI Pilot 是有該功能的實現的:

image.png
具體實現:
仍是利用方位角算法,對航線中的兩點進行向左外擴和向右外擴,示意圖如下:


image.png


紅線是我們外擴的距離,該距離爲航線間隔距離即可。我們知道線是由兩點構成的,也即意味着,航點集是一個偶數,那麼我們可以每次以步長爲 2 進行循環遍歷航點集,每次取兩個點進行經度的比較,如果 點1 的經度大於 點2 的經度,那麼 點1 就要向右進行外擴, 點2 就要向左進行外擴,外擴算出來的點需要替換原集合位置的點,以此類推下去,即可實現所有點的外擴,實現效果如下:


a.gif

參考文章

1、方位角的計算

最後

如果有開發者對無人機相關內容感興趣的話,可以聯繫作者,微信號:codelang94

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