Skip to content

Commit

Permalink
Merge pull request #49 from meadej/main
Browse files Browse the repository at this point in the history
Cleaned up repository by moving edge-detect capability to own repository. Enhanced metadata that camera saves.
  • Loading branch information
meadej committed Mar 13, 2023
2 parents 3d3db34 + 333d6dc commit 6dfa866
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 2,395 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/dockerbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ jobs:
- name: Build Images
env:
# Every folder in the repo that has a Dockerfile within it, comma separated
DOCKERFOLDERS: "edge-detect/ai,tracker,piaware,pan-tilt-pi,notebook-server,egi,axis-ptz"
DOCKERFOLDERS: "tracker,piaware,pan-tilt-pi,notebook-server,egi,axis-ptz"
PROJECT_NAME: "skyscan"
REPO_NAME: "${{ secrets.DOCKER_NAMESPACE }}"
run: |
IFS=","
read -ra ARR <<< "$DOCKERFOLDERS"
Expand All @@ -52,7 +53,7 @@ jobs:
echo "Building $folder"
echo $SUBNAME
docker buildx build "$folder" --push \
--tag iqtlabs/$PROJECT_NAME-$SUBNAME:latest \
--tag iqtlabs/$PROJECT_NAME-$SUBNAME:${{ steps.get_tag.outputs.IMAGE_TAG }} \
--tag $REPO_NAME/$PROJECT_NAME-$SUBNAME:latest \
--tag $REPO_NAME/$PROJECT_NAME-$SUBNAME:${{ steps.get_tag.outputs.IMAGE_TAG }} \
--platform linux/arm64,linux/amd64
done
150 changes: 104 additions & 46 deletions axis-ptz/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,50 @@
camera_yaw = 0

currentPlane = None

camera_altitude = None
camera_latitude = None
camera_longitude = None
camera_altitude = None

camera_lead = None
include_age = strtobool(os.getenv("INCLUDE_AGE", "True"))

def calculate_bearing_correction(b):
return (b + cameraBearingCorrection) % 360

def _format_file_save_filepath(file_extension: str = None):
"""
A method for formatting the filepath of an image based off of the current state of global variables.
For use in JPEG, BMP, and JSON saving.
Args:
file_extension: The desired file extension with leading dot (.jpg, .bmp)
Returns:
A String object representing the filepath without the filetype extension.
"""
captureDir = None

if args.flat_file_structure:
captureDir = "capture"
else:
captureDir = "capture{}".format(currentPlane["type"])
try:
os.makedirs(captureDir)
except OSError as e:
if e.errno != errno.EEXIST:
raise # This was not a "directory exist" error..
filepath = "{}/{}_{}_{}_{}_{}".format(
captureDir,
currentPlane["icao24"],
int(bearing),
int(elevation),
int(distance3d),
datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
)

if file_extension is not None:
filepath = filepath + str(file_extension)

return str(filepath)


# Copied from VaPix/Sensecam to customize the folder structure for saving pictures
def get_jpeg_request(): # 5.2.4.1
Expand Down Expand Up @@ -139,25 +173,7 @@ def get_jpeg_request(): # 5.2.4.1

disk_time = datetime.now()
if resp.status_code == 200:
captureDir = None

if args.flat_file_structure:
captureDir = "capture/"
else:
captureDir = "capture/{}".format(currentPlane["type"])
try:
os.makedirs(captureDir)
except OSError as e:
if e.errno != errno.EEXIST:
raise # This was not a "directory exist" error..
filename = "{}/{}_{}_{}_{}_{}.jpg".format(
captureDir,
currentPlane["icao24"],
int(bearing),
int(elevation),
int(distance3d),
datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
)
filename = _format_file_save_filepath(file_extension=".jpg")

# Original
with open(filename, "wb") as var:
Expand Down Expand Up @@ -224,20 +240,7 @@ def get_bmp_request(): # 5.2.4.1
)

if resp.status_code == 200:
captureDir = "capture/{}".format(currentPlane["type"])
try:
os.makedirs(captureDir)
except OSError as e:
if e.errno != errno.EEXIST:
raise # This was not a "directory exist" error..
filename = "{}/{}_{}_{}_{}_{}.bmp".format(
captureDir,
currentPlane["icao24"],
int(bearing),
int(elevation),
int(distance3d),
datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
)
filename = _format_file_save_filepath(file_extension=".bmp")

with open(filename, "wb") as var:
var.write(resp.content)
Expand Down Expand Up @@ -522,8 +525,40 @@ def calculateCameraPositionA():
)
cameraPan = calculate_bearing_correction(cameraPan)

def get_json_request():
"""
A method to save the metadata of the currently-tracking aircraft and the camera to a JSON file alongside BMP and
JPEG requests.
Args:
None
Returns:
A dictionary containing the contents os the JSON metadata file.
"""
image_filepath = _format_file_save_filepath(file_extension=".jpg")

file_content_dictionary = {
"timestamp": datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
"imagefile": image_filepath,
"camera": {
"bearing": bearing,
"zoom": cameraZoom,
"pan": cameraPan,
"tilt": cameraTilt,
"lat": camera_latitude,
"long": camera_longitude,
"alt": camera_altitude
},
"aircraft": {
"lat": currentPlane["lat"],
"long": currentPlane["lon"],
"alt": currentPlane["altitude"]
}
}

return file_content_dictionary

def moveCamera(ip, username, password):

def moveCamera(ip, username, password, mqtt_client):

movePeriod = 100 # milliseconds
moveTimeout = datetime.now()
Expand Down Expand Up @@ -582,6 +617,13 @@ def moveCamera(ip, username, password):
if captureTimeout <= datetime.now():
time.sleep(cameraDelay)
get_jpeg_request()
capture_metadata = get_json_request()
mqtt_client.publish(
"skyscan/captures/data",
json.dumps(capture_metadata),
0,
False
)
captureTimeout = captureTimeout + timedelta(
milliseconds=capturePeriod
)
Expand Down Expand Up @@ -774,6 +816,7 @@ def main():
global cameraConfig
global flight_topic
global object_topic
global logging_directory
global Active

parser = argparse.ArgumentParser(description="An MQTT based camera controller")
Expand Down Expand Up @@ -836,7 +879,19 @@ def main():
help="The zoom setting for the camera (0-9999)",
default=9999,
)
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
parser.add_argument(
"-l",
"--log-directory",
type=str,
help="The directory for the camera to write capture logs to.",
default="/flash/processed/log"
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
help="Verbose output"
)
parser.add_argument(
"-f",
"--flat-file-structure",
Expand Down Expand Up @@ -897,15 +952,8 @@ def main():
camera_lead = args.camera_lead
# cameraConfig = vapix_config.CameraConfiguration(args.axis_ip, args.axis_username, args.axis_password)

cameraMove = threading.Thread(
target=moveCamera,
args=[args.axis_ip, args.axis_username, args.axis_password],
daemon=True,
)
cameraMove.start()
# Sleep for a bit so we're not hammering the HAT with updates
delay = 0.005
time.sleep(delay)
logging_directory = args.log_directory

flight_topic = args.mqtt_flight_topic
object_topic = args.mqtt_object_topic
print(
Expand Down Expand Up @@ -933,6 +981,16 @@ def main():
False,
)

cameraMove = threading.Thread(
target=moveCamera,
args=[args.axis_ip, args.axis_username, args.axis_password, client],
daemon=True,
)
cameraMove.start()
# Sleep for a bit so we're not hammering the HAT with updates
delay = 0.005
time.sleep(delay)

#############################################
## Main Loop ##
#############################################
Expand Down
15 changes: 0 additions & 15 deletions edge-detect/README.md

This file was deleted.

35 changes: 0 additions & 35 deletions edge-detect/ai/Dockerfile

This file was deleted.

Loading

0 comments on commit 6dfa866

Please sign in to comment.