Skip to content

Commit 8ada027

Browse files
committed
Support custom launch in sub missions
1 parent a4a8c7f commit 8ada027

3 files changed

Lines changed: 126 additions & 12 deletions

File tree

DESCRIPTION

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: flightplanning
22
Type: Package
3-
Title: UAV Flight Planning
4-
Version: 0.8.4
3+
Title: Hivemapper/UAV Flight Planning
4+
Version: 0.8.14
55
Authors@R: c(
66
person("Caio", "Hamamura", email = "caiohamamura@gmail.com", role = c("aut", "cre")),
77
person("Danilo Roberti Alves de", "Almeida", email = "daniloflorestas@gmail.com", role = c("aut")),
@@ -22,5 +22,3 @@ License: MIT + file LICENSE
2222
Encoding: UTF-8
2323
LazyData: true
2424
RoxygenNote: 7.1.0
25-
URL: https://github.com/caiohamamura/flightplanning-R
26-
BugReports: https://github.com/caiohamamura/flightplanning-R/issues

R/main.R

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@ MIN_PHOTO_INTERVAL = 2
22
DIAG_35MM = sqrt(36^2 + 24^2) # Classical 35mm film diagonal
33
MAX_WAYPOINTS = 99
44

5+
# Calculate distance in meters between two points
6+
earth.dist <- function (long1, lat1, long2, lat2)
7+
{
8+
rad <- pi/180
9+
a1 <- lat1 * rad
10+
a2 <- long1 * rad
11+
b1 <- lat2 * rad
12+
b2 <- long2 * rad
13+
dlon <- b2 - a2
14+
dlat <- b1 - a1
15+
a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
16+
c <- 2 * atan2(sqrt(a), sqrt(1 - a))
17+
R <- 6378.145
18+
d <- R * c
19+
return(d * 1000)
20+
}
21+
522
#' Function to generate Litchi csv flight plan
623
#'
724
#'
@@ -249,13 +266,12 @@ litchi.plan = function(roi, output,
249266

250267

251268
# Check if launch point has been specified before inserting it as way-point 1
252-
if ((launch[1] == 0) && (launch[2] == 0)) {
253-
message("No launch point specified")
269+
hasCustomLaunch = (launch[1] != 0) || (launch[2] != 0)
270+
if (hasCustomLaunch) {
271+
message("Launch point specified: ", launch[1], ',', launch[2])
272+
MAX_WAYPOINTS = MAX_WAYPOINTS - 1
254273
} else {
255-
launchdf = data.frame(launch[1], launch[2], FALSE, FALSE)
256-
names(launchdf) = c("x", "y", "isCurve", "takePhoto")
257-
tempdf = rbind(launchdf, waypoints)
258-
waypoints = tempdf
274+
message("No launch point specified")
259275
}
260276

261277

@@ -293,7 +309,6 @@ litchi.plan = function(roi, output,
293309
dfLitchi$actiontype1 = 5
294310
dfLitchi$actionparam1 = gimbal.pitch.angle
295311

296-
297312
# Split the flight if is too long
298313
dists = sqrt(diff(waypoints[,1])**2+diff(waypoints[,2])**2)
299314
distAcum = c(0,cumsum(dists))
@@ -313,11 +328,112 @@ litchi.plan = function(roi, output,
313328

314329
dfLitchi$split = rep(1:nBreaks, diff(c(0, waypointsBreak, finalSize)))
315330
splits = split.data.frame(dfLitchi, f = dfLitchi$split)
331+
332+
if (hasCustomLaunch) {
333+
p0x = launch[[1]][1]
334+
p0y = launch[[2]][1]
335+
message(p0x)
336+
message(p0y)
337+
338+
launch84 = rgdal::rawTransform(roi@proj4string@projargs, wgs84, as.integer(1), launch[[1]], launch[[2]])
339+
message(roi@proj4string@projargs)
340+
message(wgs84)
341+
342+
overage = NULL
343+
344+
for (i in 1:length(splits)) {
345+
message(i)
346+
message(splits[[i]])
347+
348+
if (!is.null(overage)) {
349+
message('handling overage')
350+
message(overage)
351+
splits[[i]] = rbind(overage, splits[[i]])
352+
} else {
353+
message('no overage')
354+
}
355+
356+
message('mercator...')
357+
# mercator = rgdal::rawTransform(wgs84, roi@proj4string@projargs, length(splits[[i]]), splits[[i]]$latitude, splits[[i]]$longitude)
358+
mercator = rgdal::rawTransform("+init=epsg:4326", "+init=epsg:3857", length(splits[[i]]), splits[[i]]$latitude, splits[[i]]$longitude)
359+
message("MERCATOR")
360+
# message(mercator)
361+
# p1x = splits[[i]]$latitude[1]
362+
# p1y = splits[[i]]$longitude[1]
363+
message(colnames(mercator))
364+
p1x = mercator[[1]][1]
365+
p1y = mercator[[2]][1]
366+
message(p1x)
367+
message(p1y)
368+
dx = p1x - p0x
369+
dy = p1y - p0y
370+
distance = earth.dist(launch84[[1]][1], launch84[[2]][1], splits[[i]]$longitude[1], splits[[i]]$latitude[1])
371+
message(launch84[[2]][1], launch84[[1]][1], splits[[i]]$longitude[1], splits[[i]]$latitude[1])
372+
message(distance)
373+
message(max.waypoints.distance)
374+
375+
376+
interpPtsToAdd = floor(distance / max.waypoints.distance)
377+
nPtsToAdd = 1 + interpPtsToAdd
378+
379+
message('ptsToAdd...')
380+
ptsToAdd = rbind(splits[[i]][1:min(nrow(splits[[i]]), nPtsToAdd),])
381+
ptsToAdd$curvesize.m. <- 0
382+
ptsToAdd$photo_distinterval <- 0
383+
ptsToAdd$photo_timeinterval <- 0
384+
385+
message(nPtsToAdd)
386+
387+
toConvert = data.frame(
388+
lat = numeric(nPtsToAdd),
389+
lon = numeric(nPtsToAdd)
390+
)
391+
392+
toConvert[1,] = c(p0x, p0y)
393+
if (nPtsToAdd > 1) {
394+
for (j in 2:nPtsToAdd) {
395+
message('interpolating ', nPtsToAdd, ': ', c(p0x + ((j - 1) / nPtsToAdd) * dx, p0y + ((j - 1) / nPtsToAdd) * dy))
396+
toConvert[j,] <- c(p0x + ((j - 1) / nPtsToAdd) * dx, p0y + ((j - 1) / nPtsToAdd) * dy)
397+
}
398+
}
399+
400+
wgs84 = rgdal::rawTransform("+init=epsg:3857", "+init=epsg:4326", length(toConvert), toConvert$lat, toConvert$lon)
401+
message("WGS84")
402+
message(wgs84)
403+
404+
ptsToAdd$latitude = wgs84[[2]]
405+
ptsToAdd$longitude = wgs84[[1]]
406+
407+
dataSize = length(splits[[i]])
408+
lim = min(MAX_WAYPOINTS + 1, dataSize)
409+
rem = 0
410+
if (dataSize + nPtsToAdd > MAX_WAYPOINTS + 1) {
411+
rem = dataSize + nPtsToAdd - (MAX_WAYPOINTS + 1)
412+
}
413+
414+
splits[[i]] = rbind(ptsToAdd, splits[[i]][1:lim,])
415+
416+
if (rem > 0) {
417+
overage = splits[[i]][lim + 1:length(splits[[i]]),]
418+
} else {
419+
overage = NULL
420+
}
421+
422+
message("FINAL ", i)
423+
message(splits[[i]])
424+
}
425+
426+
if (!is.null(overage)) {
427+
splits[length(splits) + 1] = rbind(overage)
428+
}
429+
}
430+
316431
if (nrow(waypoints) > MAX_WAYPOINTS) {
317432
message("Your flight was split into ", length(splits), " sub-flights,
318433
because the number of waypoints ", nrow(waypoints), " exceeds the maximum of ", MAX_WAYPOINTS, ".")
319434
}
320435
else {
436+
# XXX flight time doesn't include custom launch point stuff
321437
message("Your flight was split into ", length(splits), " sub-flights,
322438
because the total flight time of ", round(totalFlightTime, 2), " minutes exceeds the max of ", max.flight.time, " minutes.")
323439
}

R/utils.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#'
33
#' @description
44
#' Calculates the minimum oriented bounding box using the
5-
#' rotating claipers algorithm.
5+
#' rotating calipers algorithm.
66
#' Credits go to Daniel Wollschlaeger <https://github.com/ramnathv>
77
#'
88
#' @param xy A matrix of xy values from which to calculate the minimum oriented

0 commit comments

Comments
 (0)