moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Applying live gps location to raspistill exif data

Mon Aug 20, 2018 10:15 pm

The objective is to take images with the pi noir camera using raspistill and add the gps data from a ublox neo-6m gps module to the exif data in real time. This is intended to be mounted in a uav for agricultural mapping.

I have the raspberry pi Zero W running raspian with a ublox neo -6m module attached to the serial of the Zero W. I have got the gps data coming through on cat /dev/serial0 and cat /dev/ttyS0. I also have valid gps data using gpsmon /dev/ttyS0 and cgps.

I am amble to take still images from the pi noir using raspistill and save them to file.

The problem is getting raspistill to attach the gps data to the exif data of the image file. I have been following this thread and this document which are very helpful but seem to be missing the important link between manually adding gps data and adding real time gps data.

If I use
:

Code: Select all

sudo raspistill -v -o /home/pi/Pictures/uav_images/image%04d.jpg --exif GPS.GPSLatitude=1 --exif GPS.GPSLongitudeRef --exif GPS.GPSAltitude=1 --exif GPS.GPSTimeStamp=1 --exif GPS.GPSImgDirection=1

I get exif data as follows:

Code: Select all

ExifTool Version Number         : 10.40
File Name                       : image-001.jpg
Directory                       : /home/pi/Pictures/uav_images
File Size                       : 4.0 MB
File Modification Date/Time     : 2018:08:21 08:05:16+10:00
File Access Date/Time           : 2018:08:21 08:05:15+10:00
File Inode Change Date/Time     : 2018:08:21 08:05:16+10:00
File Permissions                : rw-r--r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian (Motorola, MM)
Make                            : RaspberryPi
Camera Model Name               : RP_imx219
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Modify Date                     : 2018:08:21 08:05:15
Y Cb Cr Positioning             : Centered
Exposure Time                   : 1/61
F Number                        : 2.0
Exposure Program                : Aperture-priority AE
ISO                             : 50
Exif Version                    : 0220
Date/Time Original              : 2018:08:21 08:05:15
Create Date                     : 2018:08:21 08:05:15
Components Configuration        : Y, Cb, Cr, -
Shutter Speed Value             : 1/61
Aperture Value                  : 2.0
Brightness Value                : 2.58
Max Aperture Value              : 2.0
Metering Mode                   : Center-weighted average
Flash                           : No Flash
Focal Length                    : 3.0 mm
Maker Note Unknown Text         : (Binary data 336 bytes, use -b option to extract)
Flashpix Version                : 0100
Color Space                     : sRGB
Exif Image Width                : 3280
Exif Image Height               : 2464
Interoperability Index          : R98 - DCF basic file (sRGB)
Exposure Mode                   : Auto
White Balance                   : Auto
GPS Latitude                    : 1 deg 0' 0.00"
GPS Altitude                    : 1 m
GPS Time Stamp                  : 01:00:00
GPS Img Direction               : 1
Compression                     : JPEG (old-style)
Thumbnail Offset                : 1152
Thumbnail Length                : 24576
Image Width                     : 3280
Image Height                    : 2464
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Aperture                        : 2.0
Image Size                      : 3280x2464
Megapixels                      : 8.1
Shutter Speed                   : 1/61
Thumbnail Image                 : (Binary data 24576 bytes, use -b option to extract)
Focal Length                    : 3.0 mm
Light Value                     : 8.9

I have also tried:

Code: Select all

  sudo raspistill -t 1 -v -o /home/pi/Pictures/uav_images/image%04d.jpg --exif GPS.GPSLatitude=ALT --exif GPS.GPSLongitude=LONG --exif GPS.GPSAltitude=ALT --exif GPS.GPSTimeStamp=1 --exif GPS.GPSImgDirection=1

sudo raspistill -t 1 -v -o /home/pi/Pictures/uav_images/image1.jpg --exif GPS.GPSLatitude=gpsd.fix.latitude --exif GPS.GPSLongitude=gpsd.fix.longitude --exif GPS.GPSAltitude=gpsd.fix.altitude --exif GPS.GPSTimeStamp=1 --exif GPS.GPSImgDirection=1
With the same results.

Sample output from cgps:

Code: Select all

  Time:       2018-08-20T22:11:21.000Z   ││PRN:   Elev:  Azim:  SNR:  Used: │
│    Latitude:    25.644935 S               ││   1    48    248    26      Y   │
│    Longitude:  151.932069 E               ││   3    23    222    25      Y   │
│    Altitude:   239.8 m                    ││  10    18    067    18      Y   │
│    Speed:      0.5 kph                    ││  11    34    279    17      Y   │
│    Heading:    0.0 deg (true)             ││  14    39    146    33      Y   │
│    Climb:      0.0 m/min                  ││  18    58    291    18      Y   │
│    Status:     3D FIX (13 secs)           ││  22    45    213    19      Y   │
│    Longitude Err:   +/- 4 m               ││  31    64    123    21      Y   │
│    Latitude Err:    +/- 9 m               ││  32    21    127    36      Y   │
│    Altitude Err:    +/- 11 m              ││                                 │
│    Course Err:      n/a                   ││                                 │
│    Speed Err:       +/- 107 kph           ││                                 │
│    Time offset:     0.742                 ││                                 │
│    Grid Square:     QG54xi                ││                                 │
└───────────────────────────────────────────┘└─────────────────────────────────┘
"az":123,"ss":21,"used":true},{"PRN":32,"el":21,"az":127,"ss":36,"used":true}]}
{"class":"GST","device":"/dev/ttyS0","time":"1970-01-03T13:25:21.000Z","rms":47.
000,"lat":9.600,"lon":4.200,"alt":12.000}
{"class":"TPV","device":"/dev/ttyS0","mode":3,"time":"2018-08-20T22:11:21.000Z",
"ept":0.005,"lat":-25.644935667,"lon":151.932069500,"alt":239.800,"epx":4.200,"e
py":9.600,"epv":11.800,"track":0.0000,"speed":0.147,"climb":0.000,"eps":29.83}
I am sure I am missing something simple here but 2 days have passed and I have not stumbled upon the solution.

Any hints would be greatly appreciated.

User avatar
topguy
Posts: 4935
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Applying live gps location to raspistill exif data

Tue Aug 21, 2018 12:04 am

Do you expect Raspistill to read the GPS location automatically from GPSD ?

Code: Select all

--exif GPS.GPSLatitude=1
results in..
GPS Latitude                    : 1 deg 0' 0.00"
So you get what you put in.. you just have to read the data from GPSD before you call raspistill with that data.

In general I would think it might be easier to add it to the picture afterwards.

The tool ExifTool can use a GPS log file and automatically geotag pictures based on their timestamp correllated with timestamp in GPS log.
https://www.sno.phy.queensu.ca/~phil/ex ... eotag.html

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Tue Aug 21, 2018 2:19 am

Yes I expect raspistill to read the GPS data. I was under the impression that this function was added to raspistill a couple of years ago.
Refer https://www.raspberrypi.org/forums/view ... p?t=102617
Maybe it is only an option not installed by default?
Adding the GPS data afterward is not really practical since I am dealing with hundreds, if not thousands of images per flight. I already have that ability using the log from the flight controller and it's a "pita".
Hence my attempt to have it all done autonomously via raspistill.

If I am wrong about raspistill being able to read the gpsd data, then how could I read the gpsd at the time of taking the image and then recording it?

User avatar
topguy
Posts: 4935
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Applying live gps location to raspistill exif data

Tue Aug 21, 2018 9:16 am

Yes I expect raspistill to read the GPS data. I was under the impression that this function was added to raspistill a couple of years ago.
That patch is still just a pull request. https://github.com/raspberrypi/userland/pull/286

But that means that you ( or someone knowlegable and kind ) can compile a version of raspistill with this feature using the github code.

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Tue Aug 21, 2018 11:18 am

Awesome, thanks TopGuy.
That solves that mystery.

Now, of course, my next problem is how to compile and use this forgotten branch of the raspistill code.

Any hints?

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Tue Aug 21, 2018 9:57 pm

I have downloaded the binary and copied it as raspistill to /opt/vc/ after renaming the original.

I then had a " error while loading shared libraries: libGLESv2.so: cannot open shared object file: No such file or directory."

So I

Code: Select all

sudo ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0 /usr/lib/libEGL.so
sudo ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0 /usr/lib/libGLESv2.so
and the error went away.

So now I can use the -gps option but then I get a "libgps.so.21: cannot open shared object file: No such file or directory" error.
So far my searching for this library has come up blank. I installed libgps-dev but still get the error.

I also don't know how to call for the required gps information.
ie
-x GPS.GPSAltitude or
-x GPS.GPSAltitude="alt" or
-x GPS.GPSAltitude=ALT or
-x GPS.GPSAltitude=gpsd.fix.altitude
etc

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Wed Aug 22, 2018 4:13 am

In case somebody stumbles upon this in search of the same answer, it turns out you don't have to call for any GPS data, it is added automatically.

raspistill -gps -q 5 -v -tl 660 -t 30000 -o pic%03d.jpg

Should return images with gps exif tags attached.

User avatar
topguy
Posts: 4935
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Applying live gps location to raspistill exif data

Wed Aug 22, 2018 9:31 am

Where did you download the binary from ? For reference to the next guy who reads this thread...
I'm guessing you discovered that you had libgps.so.22 in your system.

Both of these suggests that your system is Raspbian Strecth but the binary you downloaded was compiled on Raspbian Jessie. But if you made it work then it doesnt matter.

gordon77
Posts: 3418
Joined: Sun Aug 05, 2012 3:12 pm

Re: Applying live gps location to raspistill exif data

Wed Aug 22, 2018 10:14 am

topguy wrote:
Wed Aug 22, 2018 9:31 am
Where did you download the binary from ? For reference to the next guy who reads this thread...
I'm guessing you discovered that you had libgps.so.22 in your system.

Both of these suggests that your system is Raspbian Strecth but the binary you downloaded was compiled on Raspbian Jessie. But if you made it work then it doesnt matter.
it's in this thread https://github.com/raspberrypi/userland/pull/286

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Wed Aug 22, 2018 10:25 pm

I think that IS where I got the binary from, yes.
I had to rename libgps.so.22 to ligps.so.21 but other than that...........

I have one more problem with this though.
The -gps function apparently only works when raspistill is in continuous mode. I am looking for a work around so my flight controller can trigger single images and still get the gps exif tags.

I have tried:
Run the camera forever, taking a picture when Enter is pressed:

raspistill -t 0 -k -o my_pics%02d.jpg
from a console and I am able to trigger individual images AND have them geotagged so now I need to know how to trigger this from the flight controller via GPIO.

I really appreciate the help every body offers in the raspberry pi community. So much better than some other forums I have visited.

User avatar
topguy
Posts: 4935
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Applying live gps location to raspistill exif data

Thu Aug 23, 2018 9:08 am

I am looking for a work around so my flight controller can trigger single images and still get the gps exif tags.
How did you plan to take/trigger images from the flight controller in the first place ?

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Thu Aug 23, 2018 12:41 pm

With the pi and noir cam?
I was simply going to read the gpio and execute a script when the gpio goes high. The pixhawk flight controller is 3.3v and can send an output high to trigger an image at a particular point in the flight plan. This happens over hundreds or even thousands of times during a grid survey flight plan.

Of course this requires that the pi only takes one image at each trigger point and must be able to take the next image when triggered in a relatively short time span. ie <1 sec.

My thought were something along the lines of this: (which does not work)

Code: Select all

import RPi.GPIO as GPIO
import os
import time


GPIO.setmode(GPIO.BCM)  
  
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
os.system("raspistill -gps -t 0 -k -o /home/pi/Pictures/uav_images/xdo-pics%04d.jpg -awb sun")
  
print "Waiting for rising edge on port 23"  

while true: 
    try:  
        GPIO.wait_for_edge(23, GPIO.RISING)  
        print "\nrising edge detected."
        os.system("xdotool key Return")
   
    except KeyboardInterrupt:  
        GPIO.cleanup()       # clean up GPIO on CTRL+C exit  
        GPIO.cleanup()           # clean up GPIO on normal exit  



User avatar
topguy
Posts: 4935
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Applying live gps location to raspistill exif data

Thu Aug 23, 2018 1:53 pm

Instead of using the function to press "enter" there is the option to send a "signal" to the process.
https://www.raspberrypi.org/forums/view ... hp?t=75571

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Fri Aug 24, 2018 2:25 am

topguy wrote:
Thu Aug 23, 2018 1:53 pm
Instead of using the function to press "enter" there is the option to send a "signal" to the process.
https://www.raspberrypi.org/forums/view ... hp?t=75571
Awesome, thanks topguy. I have that working, to a point.

Code: Select all

import RPi.GPIO as GPIO
import os
import time
import signal,subprocess,time
import datetime
import time
import sys

date = datetime.datetime.now().strftime("%m_%d_%Y_%H_%M_%S")


GPIO.setmode(GPIO.BCM)  
  
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
cmd = "/usr/bin/raspistill -gps -t 0 -s -o /home/pi/Pictures/uav_images/"+ date + "%4d.jpg"
proc = subprocess.Popen(cmd.split(), shell=False)
print "Waiting for rising edge on port 23"  

while True:
        try:  
                GPIO.wait_for_edge(23, GPIO.RISING)  
                print "\nrising edge detected."
                proc.send_signal(signal.SIGUSR1)
   
        except KeyboardInterrupt:  
                GPIO.cleanup()
This works to the point where I can set GPIO23 high and get images.
BUT, it locks the pi up and reboots after a few frames. Especially if I try to do anything else with the pi while this is running. ie, browse to the Pictures folder.
Running the raspistill command directly in a terminal is fine.

Also, I expected the date and time in the file name would prevent the overwriting of previous files, but of course, the script only sets the date and time once at the start. Not sure how to fix this either.

I am reasonably happy to code in C++ for arduino but, what I know about Python, you could write on a postage stamp with a mop!

Thanks for your patience.

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Fri Aug 24, 2018 2:53 am

I have managed to come up with an acceptable solution for the date in file name problem.

Code: Select all

date = datetime.datetime.now().strftime("%m_%d_%Y_%H_%M_%S")
#Create the folder with the full path
mydir = "/home/pi/Pictures/uav_images/"+date
os.makedirs(mydir)

GPIO.setmode(GPIO.BCM)  
  
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
cmd = "/usr/bin/raspistill -gps -t 0 -s -o /home/pi/Pictures/uav_images/"+ date + "/img_%4d.jpg"
proc = subprocess.Popen(cmd.split(), shell=False)
print "Waiting for rising edge on port 23"  
Just need to stop it from locking up and rebooting the pi.

No idea where to start on that though.

moose4621
Posts: 12
Joined: Mon Aug 20, 2018 9:32 pm

Re: Applying live gps location to raspistill exif data

Fri Aug 24, 2018 8:44 am

After reading of some issues between NOOBS and rc.local, I launched the script from /home/pi/.config/lxsession/LXDE-pi/autostart and all my problems went away.

Camera is triggered from the flight controller and gps exif data is tagged to image with a reliable repeat capture rate of approx 0.8sec.

Yay.

Ready for a test flight.
If this works it is going to make my life so much easier. Lol.

Thanks again @topguy for your help. You are awesome.

Return to “Beginners”