Skip to content

Commit

Permalink
Merge pull request #18 from hotosm/feat/shift-start-and-end-point
Browse files Browse the repository at this point in the history
feat: optimize flight path by adjusting waypoints based on takeoff point
  • Loading branch information
nrjadkry authored Sep 26, 2024
2 parents c92b66e + 755af55 commit 7c24e80
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ DJI drones require waypoint files. WPML route files all end with a ".kmz" suffix

For more details, check the [DJI Cloud API documentation](https://github.com/dji-sdk/Cloud-API-Doc/blob/master/docs/en/60.api-reference/00.dji-wpml/10.overview.md).


## Installation

To install the package, use pip:
Expand All @@ -53,26 +52,29 @@ calculate_parameters(
```

**Parameters:**

- `AGL` (Altitude above ground level in meters) = 115
- `Forward overlap` = 75
- `Side overlap` = 75

**Fixed Parameters:**

- `Image interval` = 2 sec
- `Vertical FOV` = 0.71
- `Horizontal FOV` = 1.26

**Calculations:**
- Forward Photo height = AGL * Vertical_FOV = 115 * 0.71 = 81.65
- Side Photo width = AGL * Horizontal_FOV = 115 * 1.26 = 144
- Forward overlap distance = Forward photo height * Forward overlap = 75 / 100 * 81.65 = 61.5
- Side overlap distance = Side photo width * Side overlap = 75 / 100 * 144 = 108

- Forward Photo height = AGL *Vertical_FOV = 115* 0.71 = 81.65
- Side Photo width = AGL *Horizontal_FOV = 115* 1.26 = 144
- Forward overlap distance = Forward photo height *Forward overlap = 75 / 100* 81.65 = 61.5
- Side overlap distance = Side photo width *Side overlap = 75 / 100* 144 = 108
- Forward spacing = Forward photo height - Forward overlap distance = 81.65 - 61.5 = 20.15
- Side spacing = Side photo width - Side overlap distance = 144 - 108 = 36
- Ground speed = Forward spacing / Image interval = 10


**Parameters:**

- `waypoints_geojson`: The waypoint coordinates to be included in the flight plan mission.
- `parameters`: The drone flight parameters in JSON format.

Expand All @@ -98,6 +100,7 @@ create_waypoint(
```

**Parameters:**

- `project_area` (dict): A GeoJSON dictionary representing the project area (Polygon AOI).
- `agl` (float): Altitude above ground level (the height at which the drone will fly).
- `gsd` (float): Ground Sampling Distance (resolution of the images captured).
Expand All @@ -120,6 +123,7 @@ add_elevation_from_dem(raster_file, points, outfile)
```

**Parameters:**

- `raster_file`: Path to the DEM GeoTIFF file.
- `points`: GeoJSON string with point coordinates.
- `outfile`: Path for saving the output with added elevation.
Expand All @@ -137,7 +141,6 @@ create_placemarks(
)
```


### 5. `create_wpml`

This module is responsible for creating WPML files (Waypoint Markup Language), which are often used for visualizing waypoints and flight paths in different tools or simulators:
Expand All @@ -152,6 +155,7 @@ create_wpml(
```

**Parameters:**

- `placemark_geojson`: The placemark coordinates to be included in the flight plan mission.
- `output_file_path`: The output file path for the WPML file.

Expand All @@ -178,6 +182,7 @@ create_flightplan(
```

**Parameters:**

- `aoi`: The area of interest in GeoJSON format.
- `forward_overlap` (float): Desired forward overlap percentage for the images.
- `side_overlap` (float): Desired side overlap percentage for the images.
Expand All @@ -189,6 +194,3 @@ create_flightplan(
- `generate_each_points` (bool, optional): True to generate individual waypoints for flight, False to generate waylines.
- `rotation_angle` (float, optional): The rotation angle (in degrees) for the flight grid. Default is 0.0.
- `take_off_point` (list[float], optional): A list of GPS coordinates [longitude, latitude] for the takeoff point.



24 changes: 23 additions & 1 deletion drone_flightplan/waypoints.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import argparse
from math import sqrt
import pyproj
import geojson
from shapely.geometry import Point, shape, Polygon
Expand Down Expand Up @@ -41,8 +42,18 @@ def generate_grid_in_aoi(
return points


def calculate_distance(point1, point2):
"""
Calculate Euclidean distance between two points.
"""
return sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2)


def create_path(
points: list[Point], forward_spacing: float, generate_3d: bool = False
points: list[Point],
forward_spacing: float,
generate_3d: bool = False,
take_off_point: list[float] = None,
) -> list[dict]:
"""
Create a continuous path of waypoints from a grid of points.
Expand Down Expand Up @@ -305,6 +316,17 @@ def create_waypoint(

# Conditionally add takeoff point if available
if take_off_point:

# Get the first and last point of the initial path
first_path_point = initial_path[0]["coordinates"]
last_path_point = initial_path[-1]["coordinates"]

# Calculate distances from the takeoff point
distance_to_first = calculate_distance(Point(transformer_to_3857(*take_off_point)), first_path_point)
distance_to_last = calculate_distance(Point(transformer_to_3857(*take_off_point)), last_path_point)
if distance_to_last < distance_to_first:
initial_path.reverse()

initial_point = {
"coordinates": Point(transformer_to_3857(*take_off_point)),
"take_photo": False,
Expand Down

0 comments on commit 7c24e80

Please sign in to comment.