Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaned up repository by moving edge-detect capability to own repository. Enhanced metadata that camera saves. #49

Merged
merged 4 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.