Software for generating grid coordinates that Litchi can use

Joined
Aug 17, 2016
Messages
53
Reaction score
7
Age
70
Location
Weston, Florida
I am getting my commercial drone license and want to fly for a company that photographs building roofs and walls. The detail roof photos require you to take multiple photographs at a certain height and overlap. This is a perfect application of Litchi waypoints and I have been practicing on my home. I found 2 problems very quickly. The first one is that there are lots of photos to take, so that means a lot of repetitive adding of waypoints, setting heading, setting gimbal pitch, adding action to take photo, basically a bit boring. And the other problem is even using the Mission Hub software on my desktop computer the map doesn't zoom in close enough so you have room for all the waypoints. They are just one on top of the other.

This seems the perfect application of a computer program that could compute the waypoints and write them into a csv file that could be imported into Mission Hub as the start of a mission with only a few mission settings needing to be set by hand. I am a computer programmer and can write a program to do this but it seems silly to reinvent the wheel as there has to be shareware code out there that already does all or part of that but I haven't been able to find any with google searches. I either find programs you have to buy or programs for computing grids, but not geo grids.

Can anyone steer me to something I can use? Here is an example of what the drone needs to do.

lawnmower.jpg
 
Okay, I wrote a simple Python program that draws a grid of waypoints equally spaced starting at the southwest corner of the structure you want to photograph. I used Python 3.5 but I think it will work for Python 2.7 as well. You can control how close the waypoints are and their height. Here is an example how it works using my house in Litchi Mission Hub.

Screen Shot 2017-02-05 at 12.13.23 AM.png


Here is my home overlaid with waypoints angled the same way my house is angled. The program generated a waypoint grid of 5 rows and 3 columns because that is what I specified, but it is easily changed where the routine is called.

Screen Shot 2017-02-05 at 12.13.31 AM.png


It writes the waypoints to a csv file called waypoints.csv. This csv can then be imported into Mission Hub and adjusted. Now you can just trim away any waypoints that are unnecessary and make any other adjustments.

Screen Shot 2017-02-05 at 12.13.48 AM.png


Here is the code. It is fairly self-explanatory.

Code:
import os, sys
from math import sin, cos, radians, pi
from pyproj import Proj, transform

# per http://spatialreference.org/ref/epsg/
# EPSG Projection List
fleast_ft = Proj(init='esri:102658') # NAD_1983_StatePlane_Florida_East_FIPS_0901_Feet
fleast_m = Proj(init='esri:102258')  # NAD_1983_HARN_StatePlane_Florida_East_FIPS_0901
wgs84 = Proj(proj='latlong',datum='WGS84')
M2FT = 3.2808399
FT2M = (1.0/M2FT)

def point_pos(x0, y0, d, theta):
    theta_rad = pi/2 - radians(theta)
    return x0 + d*cos(theta_rad), y0 + d*sin(theta_rad)

def getPlaneCoordinates(lat, lon):
    x, y, z = transform(wgs84,fleast_m,lon,lat,0.0)
    return x*M2FT,y*M2FT

def getGeoCoordinates(x, y):
    lat, lon, depth = transform(fleast_m,wgs84,x*FT2M,y*FT2M,0.0)
    return lon, lat

# lat, lon of southwest corner of property
def calulate_points(lat, lon, dist_between_waypoints, heading, num_rows, num_cols, drone_height):
   half_dist = dist_between_waypoints/2
   x,y = getPlaneCoordinates(lat, lon)
   f = open('waypoints.csv', 'w')
   f.write("latitude,longitude,altitude(ft),heading(deg),curvesize(ft),rotationdir,gimbalmode,gimbalpitchangle,actiontype1,actionparam1,actiontype2,actionparam2,actiontype3,actionparam3,actiontype4,actionparam4,actiontype5,actionparam5,actiontype6,actionparam6,actiontype7,actionparam7,actiontype8,actionparam8,actiontype9,actionparam9,actiontype10,actionparam10,actiontype11,actionparam11,actiontype12,actionparam12,actiontype13,actionparam13,actiontype14,actionparam14,actiontype15,actionparam15\n")
   for i in range(0,num_cols):
       col_offset = half_dist*(2*i+1)
       x1, y1 = point_pos(x, y, col_offset, (heading+90)%360)
       for j in range(0,num_rows):
           if i % 2:
               row_offset = half_dist*((num_rows-j)*2-2)
           else:
               row_offset = half_dist*(2*j)
           x2, y2 = point_pos(x1, y1, row_offset, heading)
           lat2, lon2 = getGeoCoordinates(x2, y2)
           # write the computed values
           f.write(",".join([str(lat2),str(lon2),str(drone_height),str(heading)]))
           # write the hardcoded values - set gimbel pitch to interpolate and gimbel angle to straight down, add action to take photo
           f.write(",0,0,2,-90,1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0\n")

if __name__ == '__main__':
    calulate_points(26.127593, -80.423116, 15, 14, 5, 3, 40)
 
Last edited:
It looks like you're doing Betterview's test mission. I did it also and my first thought was to do it autonomously as you are but after a little thought I figured it would be easier to just do it manually, not because litchi is difficult (it's not) but it just seemed to be a waste of time to plan the mission. What they show in the example of how to take the pics is overkill of how many pics you actually need to take. They ask for a 20% overlap. If I took the pics according to their example it would be about 60%. Try it manually as well as autonomously. You may just want to skip planning a mission. Again, this advice is if you're doing shots for Betterview. Good luck.


Sent from my iPhone using PhantomPilots
 
Use DroneDeploy or the other app suggested above.
 
I am getting my commercial drone license and want to fly for a company that photographs building roofs and walls. The detail roof photos require you to take multiple photographs at a certain height and overlap. This is a perfect application of Litchi waypoints and I have been practicing on my home. I found 2 problems very quickly. The first one is that there are lots of photos to take, so that means a lot of repetitive adding of waypoints, setting heading, setting gimbal pitch, adding action to take photo, basically a bit boring. And the other problem is even using the Mission Hub software on my desktop computer the map doesn't zoom in close enough so you have room for all the waypoints. They are just one on top of the other.

This seems the perfect application of a computer program that could compute the waypoints and write them into a csv file that could be imported into Mission Hub as the start of a mission with only a few mission settings needing to be set by hand. I am a computer programmer and can write a program to do this but it seems silly to reinvent the wheel as there has to be shareware code out there that already does all or part of that but I haven't been able to find any with google searches. I either find programs you have to buy or programs for computing grids, but not geo grids.

Can anyone steer me to something I can use? Here is an example of what the drone needs to do.

View attachment 75351
Use pix4d

Sent from my SM-G920P using Tapatalk
 
Take a look at maps made easy too.
 
Okay, I wrote a simple Python program that draws a grid of waypoints equally spaced starting at the southwest corner of the structure you want to photograph. I used Python 3.5 but I think it will work for Python 2.7 as well. You can control how close the waypoints are and their height. Here is an example how it works using my house in Litchi Mission Hub.

View attachment 75376

Here is my home overlaid with waypoints angled the same way my house is angled. The program generated a waypoint grid of 5 rows and 3 columns because that is what I specified, but it is easily changed where the routine is called.

View attachment 75377

It writes the waypoints to a csv file called waypoints.csv. This csv can then be imported into Mission Hub and adjusted. Now you can just trim away any waypoints that are unnecessary and make any other adjustments.

View attachment 75378

Here is the code. It is fairly self-explanatory.

Code:
import os, sys
from math import sin, cos, radians, pi
from pyproj import Proj, transform

# per http://spatialreference.org/ref/epsg/
# EPSG Projection List
fleast_ft = Proj(init='esri:102658') # NAD_1983_StatePlane_Florida_East_FIPS_0901_Feet
fleast_m = Proj(init='esri:102258')  # NAD_1983_HARN_StatePlane_Florida_East_FIPS_0901
wgs84 = Proj(proj='latlong',datum='WGS84')
M2FT = 3.2808399
FT2M = (1.0/M2FT)

def point_pos(x0, y0, d, theta):
    theta_rad = pi/2 - radians(theta)
    return x0 + d*cos(theta_rad), y0 + d*sin(theta_rad)

def getPlaneCoordinates(lat, lon):
    x, y, z = transform(wgs84,fleast_m,lon,lat,0.0)
    return x*M2FT,y*M2FT

def getGeoCoordinates(x, y):
    lat, lon, depth = transform(fleast_m,wgs84,x*FT2M,y*FT2M,0.0)
    return lon, lat

# lat, lon of southwest corner of property
def calulate_points(lat, lon, dist_between_waypoints, heading, num_rows, num_cols, drone_height):
   half_dist = dist_between_waypoints/2
   x,y = getPlaneCoordinates(lat, lon)
   f = open('waypoints.csv', 'w')
   f.write("latitude,longitude,altitude(ft),heading(deg),curvesize(ft),rotationdir,gimbalmode,gimbalpitchangle,actiontype1,actionparam1,actiontype2,actionparam2,actiontype3,actionparam3,actiontype4,actionparam4,actiontype5,actionparam5,actiontype6,actionparam6,actiontype7,actionparam7,actiontype8,actionparam8,actiontype9,actionparam9,actiontype10,actionparam10,actiontype11,actionparam11,actiontype12,actionparam12,actiontype13,actionparam13,actiontype14,actionparam14,actiontype15,actionparam15\n")
   for i in range(0,num_cols):
       col_offset = half_dist*(2*i+1)
       x1, y1 = point_pos(x, y, col_offset, (heading+90)%360)
       for j in range(0,num_rows):
           if i % 2:
               row_offset = half_dist*((num_rows-j)*2-2)
           else:
               row_offset = half_dist*(2*j)
           x2, y2 = point_pos(x1, y1, row_offset, heading)
           lat2, lon2 = getGeoCoordinates(x2, y2)
           # write the computed values
           f.write(",".join([str(lat2),str(lon2),str(drone_height),str(heading)]))
           # write the hardcoded values - set gimbel pitch to interpolate and gimbel angle to straight down, add action to take photo
           f.write(",0,0,2,-90,1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0\n")

if __name__ == '__main__':
    calulate_points(26.127593, -80.423116, 15, 14, 5, 3, 40)
 
@Bruce Hammond --- Bruce's Python code is PERFECT. All you do is go to the very end of it and change the parameters for "calculate_points" to values appropriate to whatever you are doing and then run it and it gives you a waypoint grid ready to import into Litchi Mission Hub.

Modify the very last line of his code as follows:
calculate_points([your_beginning_lat], [your_beginning_long], [how_far_apart_you_want_the_photos], [heading_degrees], [how_many_rows_you_want], [how_many_columns_you_want], [altititude_you_want])

Then, in mission settings, make sure to use "straight line" not "curved" so it will actually get to all the waypoints and take the pictures. Also, set "heading" to custom so that your heading value is used. Then upload to Litchi Mission hub and fly the missing.

Fantastic! Thanks again, Bruce!

 

Members online

No members online now.

Forum statistics

Threads
143,066
Messages
1,467,358
Members
104,936
Latest member
hirehackers