@@ -2,6 +2,23 @@ MIN_PHOTO_INTERVAL = 2
22DIAG_35MM = sqrt(36 ^ 2 + 24 ^ 2 ) # Classical 35mm film diagonal
33MAX_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,
318433because 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,
322438because the total flight time of " , round(totalFlightTime , 2 ), " minutes exceeds the max of " , max.flight.time , " minutes." )
323439 }
0 commit comments