Hello, All. I’m new to DIY drones community
I built my first quadcopter using Pixhawk 2.4.8 and the Copter V4.2.1 firmware and I’m using a Raspberry Pi 4 as a companion computer.
My aspiration
I am willing to take geotaged photos with an Arducam camera connected to the RPi while completing a waypoint mission autonomously.
Following ae the hardware option available for me:
Pixhawk 2.4.8
Respberry pi 4
Arducam 16mp autofocus
Objective:
Trigger Arducam automatically for taking geotagged photos while the drone is on a waypoint mission.
Is there any lead / solution that i can follow ?
Could some one please point me in right direction.
Thank you.
Hi Birendra,
It has been a while since applying these workflows, so there may be a error in my description of the process, but I think these are two approaches that may inform your efforts.
I think that you are wanting to create a mission using the survey grid tool. this will allow you to define the camera parameters to achieve the ground image you want. This tool will also allow for setting up the camera trigger for optimizing for 3D reconstruction (image sidelap and overlap. Camera triggers can be set as a high pin from one of the Autopilot output pins. You should, in theory, be able to trigger your Pi cam using this signal.
Alternatively you can set the camera trigger to a distance parameter and the signal will be sent at that interval or distance. I think this approach will work (if enabled) during a standard mission.
You can then use the geotagging tool in mission planner to correlate the cam messages to the images, creating a separate geotagged folder of the images.
Best of Luck,
Sean
A few years ago I used an RPI+RPI camera to capture images as part of the TAP-J team’s entry in the Japan Innovation Challenge search and rescue competition. This included capturing the autopilot’s location and embedding it into JPEG images. The code we used is here (I think).
After a lot of beating around the bush, I was able to capture the pictures and geotag them onboard.
Still had some issues in reading the gps data at the same time while triggering the camera and geotagging the images. I was also not sure about the accuracy. It would take a lot of effort to write fully optimised code for it.
Instead it would be easy and feasible to use Airpixel geotagger which has way more features than just geotagging, it is light weight, superfast etc, you can read about it in docs.
Assuming you have successful connection between Rpi and Pixhawk.
You can use below code as template, install python, exifread, dronekit.
import asyncio
import os
from datetime import datetime
import exifread
import dronekit
import time
import shutil
from picamera2 import Picamera2
# Define the target folder for geotagged images
TARGET_FOLDER = "/home/pi/Desktop/images/"
#1 Initialize PiCamera
picam2 = Picamera2()
#Create a new object, camera_config and use it to set the still image resolution (main) to 1920 x 1080. and a “lowres” image with a size of 640 x 480. This lowres image is used as the preview image when framing a shot.
camera_config = picam2.create_still_configuration(main={"size": (1920, 1080)}, lores={"size": (640, 480)}, display="lores")
#Load the configuration.
picam2.configure(camera_config)
#2 Connect to the drone and wait for GPS fix
print("Connecting to vehicle...")
vehicle = dronekit.connect('/dev/ttyAMA0', baud=57600)
print("Waiting for GPS fix...")
while not vehicle.gps_0.fix_type:
pass
print("GPS fix obtained.")
# Define the capture_photo function
async def capture_photo():
filename = datetime.now().strftime("%Y%m%d_%H%M%S.jpg")
temp_file = "/run/shm/{}".format(filename) # Use the ramdisk for faster I/O
picam2.start()
#Pause the code for two seconds.
time.sleep(1)
#Capture an image and save it as test.jpg.
picam2.capture_file(temp_file)
return temp_file
# Define the get_gps_data function
async def get_gps_data():
#return (vehicle.location.global_frame.lat,
# vehicle.location.global_frame.lon,
# vehicle.location.global_frame.alt)
return(39.668756, -127.334674, 10)
# Define the geotag function
async def geotag(temp_file, gps_data):
# gps_data should be a tuple containing latitude, longitude, and altitude
latitude, longitude, altitude = gps_data
# Construct the ExifTool command
exiftool_cmd = ['exiftool', '-GPSLatitude={}'.format(latitude), '-GPSLongitude={}'.format(longitude), '-GPSAltitude={}'.format(altitude), temp_file]
# Run the ExifTool command using subprocess
try:
subprocess.run(exiftool_cmd, check=True)
except subprocess.CalledProcessError as e:
print("Error geotagging photo: ", e)
return False
return True
# Define the main function
async def main():
while True:
# Wait for 5 seconds
# Capture photo and get GPS data asynchronously
temp_file_task = asyncio.create_task(capture_photo())
gps_data_task = asyncio.create_task(get_gps_data())
# Wait for both tasks to complete
temp_file = await temp_file_task
gps_data = await gps_data_task
# Geotag the image asynchronously
await geotag(temp_file, gps_data)
# Run the main function
asyncio.run(main())
In async def get_gps_data(): function you can use (I had used hard coded random value for testing)
You also you need to move geotagged image f(temp_file) to Target location of your choice…
You can add below code in async def geotag(temp_file, gps_data): function (inside try block)
Hello, All. I’m quite new to the DIY drones community and programing. I want to build a drone with a Pixhawk orange cube with Copter 4.5.1 and a computer companion Raspberry Pi 4 with its own camera module V2.
Objective:
To trigger the camera on my command from Mission Planner and Geotag the picture with the data from the Pixhawk’s GPS. I have successfully made the serial connection between the Pixhawk and Raspberry Pi. I have employed a relay module that will act as a button to trigger the RPi camera from the GPIO pin with a signal from the autopilot.
I saw this solution and I tried to add lines of code to obtain the desired result.
The main question is if the code below would work? If not could anybody point me in the right direction? Thank you all in advance for your attention!
import RPi.GPIO as GPIO
from picamera2 import Picamera2
import asyncio
import os
from datetime import datetime
import exifread
import dronekit
import time
import shutil
image_path=“/home/pi/my_captures/” #folder for iamges
camera configuration and initialization
camera = Picamera2()
camera_config = camera.create_still_configuration(main={“size”: (1920, 1080)}, lores={“size”: (640, 480)}, display=“lores”)
camera.configure(camera_config)
#Connect to the drone and wait for GPS fix
print(“Connecting to vehicle…”)
vehicle = dronekit.connect(‘/dev/ttyAMA0’, baud=57600)
print(“Waiting for GPS fix…”)
while not vehicle.gps_0.fix_type:
pass
print(“GPS fix obtained.”)
async def capture_photo(channel):
filename = datetime.now().strftime(“%Y%m%d_%H%M%S.jpg”)
temp_file = “/run/shm/{}”.format(filename) # use the ramdisk for faster I/O
camera.start_and_capture_file(temp_file)
return temp_file
Thank you for the replay. I will make the needed changes to the code and test it today. In the mean time I have a quick question about the exif data of the picture. How can I check on the Raspberry Pi if the GPS coord are saved in the correct way. So basically the question is how can I read the exif data after I finish the script?
I have see this solution ; pi@raspi /usr/freeware # time exiftool /snapshot.jpg
Hello and sorry for the late replay. I made the appropriate changes to the code and it works. Thank you for the solution and help. Now I have a follow up question to your code. Because I’m a beginner at programing , I’m a little confused with the temp_file created. I’m wondering if I could geotag the photos directly without the need of the temp_file being the intermediary, if so could you please provide an example.
Till now I’ve been working with the simple def function() and in your code I se you used asycn def function() . The question is ,if I modify your code and make all the function simple and then call them when I need them, will this ruin it?
Hi,
I’m happy to see that solution worked for you.
temp_file (image ) is stored in ram for faster read/write (exift data). you can store it in regular Sd card space but read/write operation will be slower (not ideal for geotagging ).
To do so, just replace the file path (/runn/shm/) to your SD cad path where you want to store it. temp_file = "/run/shm/{}".format(filename) # Use the ramdisk for faster I/O
Simple def function should be okay, but for time critical opration such as geotagging I have used async to capture the image and geotag at the same time. (capturing the photo and getting geolocation is done at the same time using async)
I’ve used your code and adapted it for my own use on RPI5 and using Arducam IMX519
It triggers the image capture off GPIO 16 and GND as a relay “button”
Here it is, still WIP but it’s working with GPS tagged to metadata, main change is that I’m using GPIOzero instead of RPI.GPIO. I don’t think that works on Raspberry Pi 5 at this stage
from gpiozero import Button
from picamera2 import Picamera2
import asyncio
import os
from datetime import datetime
import exifread
import dronekit
import shutil
import subprocess
# Update image storage location
image_path = "/home/PEPPIE/Desktop/ObiCam Images/"
# Camera configuration and initialization
camera = Picamera2()
camera_config = camera.create_still_configuration(
main={"size": (1920, 1080)}, lores={"size": (640, 480)}, display="lores"
)
camera.configure(camera_config)
# GPIO pin setup with GPIOZero
button = Button(16) # Change 16 to your actual GPIO pin
# Connect to the drone and wait for GPS fix
print("Connecting to vehicle...")
vehicle = dronekit.connect("/dev/ttyAMA0", baud=57600)
print("Waiting for GPS fix...")
while not vehicle.gps_0.fix_type:
pass
print("GPS fix obtained.")
async def capture_photo():
filename = datetime.now().strftime("%Y%m%d_%H%M%S.jpg")
temp_file = f"/run/shm/{filename}" # Use the ramdisk for faster I/O
camera.start_and_capture_file(temp_file)
# Move the image from temporary location to final destination
final_path = os.path.join(image_path, filename)
shutil.move(temp_file, final_path)
return final_path
async def get_gps_data():
return (
vehicle.location.global_frame.lat,
vehicle.location.global_frame.lon,
vehicle.location.global_frame.alt,
)
async def geotag(temp_file, gps_data):
latitude, longitude, altitude = gps_data
exiftool_cmd = [
"exiftool",
"-GPSLatitude={}".format(latitude),
"-GPSLongitude={}".format(longitude),
"-GPSAltitude={}".format(altitude),
temp_file,
]
try:
subprocess.run(exiftool_cmd, check=True)
except subprocess.CalledProcessError as e:
print("Error geotagging photo: ", e)
return False
return True
async def main():
while True:
# Wait for button press using GPIOZero
button.wait_for_press()
temp_file_task = asyncio.create_task(capture_photo())
gps_data_task = asyncio.create_task(get_gps_data())
temp_file = await temp_file_task
gps_data = await gps_data_task
await geotag(temp_file, gps_data)
# Execute the whole code
try:
asyncio.run(main())
except KeyboardInterrupt:
GPIOZero.cleanup()
Howdy all! I see this thread is about a year old so maybe someone pulled this off!
I am not a programmer and Linux is NOT my jam
I took a chance and bought a RPI5 Hawkeye camera
I can hook the camera up to a mouse, keyboard and a monitor
I can get the camera (RPI5 really) to properly boot and I can arrive at the desktop
I got this camera pre made and it came pre installed to work as a glorified webcam from here for $209 USD delivered.
I can also get the camera to act as a webcam and to take ONE picture via Linux commands, which acts as proof that it works.
I need what you guys needed. I want this camera to replace my MapIR Survey3N RGB camera. The MapIR is a damn fine camera for the money but I need the 64MP to more accurately find missing persons from 400 feet. I am also planning a trip to Haiti as soon as November 9th, 2025 to help them asses the CAT5 hurricane damage.
I can’t stress how much help I need in order to use this better camera.
What I need:
I need a step by step “instruction for dummies” on how to get this camera to take a geo-tagged pic when commanded to by the cube orange plus autopilot I have. In addition, I also need the geo data to come from the autopilot (Here3+ module) and not from a second external GPS unit like the Survey3 MapIR system has.
Is there any hope of getting this help this fast?? I am willing to do zoom meetings or phone calls or whatever I need to do for this upgrade!
I think we could add an extension to BlueOS (built on RPI) that adds support for the ArduCam cameras to support the mavlink camera gimbalv2 interface but not in time for your trip.
Perhaps it’s not my place to say but I don’t think a fixed camera is going to perform very well for mapping. A Siyi ZR10 or similar will perform much better I think.