-
Notifications
You must be signed in to change notification settings - Fork 39
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
Added a communication worker for logging cluster estimation #227
Changes from 13 commits
4ef1755
99f2d28
b50d714
39c55f0
1bd2cb6
89a7221
0e8263d
de18002
a0b0560
1173347
7cf4667
16cc619
8ff6035
7562a88
5599ccc
9d3b588
2501414
e4029e7
9ede6b4
2be3b1d
dea2413
76ab64f
194f0d8
df2d4de
e214595
92c3299
c7ca9c7
ce99100
4ebfdae
55755ca
affadfb
9e8df82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
""" | ||
Logs data and forwards it. | ||
""" | ||
|
||
import time | ||
|
||
from .. import object_in_world | ||
from ..common.modules.logger import logger | ||
from ..common.modules import position_global | ||
from ..common.modules import position_local | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from ..common.modules.mavlink import local_global_conversion | ||
|
||
|
||
class Communications: | ||
""" | ||
Currently logs data only. | ||
""" | ||
|
||
__create_key = object() | ||
|
||
@classmethod | ||
def create( | ||
cls, | ||
home_position: position_global.PositionGlobal, | ||
local_logger: logger.Logger, | ||
) -> "tuple[bool, Communications | None]": | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Logs data and forwards it. | ||
|
||
home_position: Take-off position of drone. | ||
|
||
Returns: Success, class object. | ||
""" | ||
|
||
return True, Communications(cls.__create_key, home_position, local_logger) | ||
|
||
def __init__( | ||
self, | ||
class_private_create_key: object, | ||
home_position: position_global.PositionGlobal, | ||
local_logger: logger.Logger, | ||
) -> None: | ||
""" | ||
Private constructor, use create() method. | ||
""" | ||
assert class_private_create_key is Communications.__create_key, "Use create() method" | ||
|
||
self.__home_position = home_position | ||
self.__logger = local_logger | ||
|
||
def run( | ||
self, | ||
objects_in_world: list[object_in_world.ObjectInWorld], | ||
) -> tuple[bool, list[object_in_world.ObjectInWorld] | None]: | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
objects_in_world_global = [] | ||
for object_in_world in objects_in_world: | ||
# TODO: Change this when the conversion interface is changed | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
north = object_in_world.location_x | ||
east = object_in_world.location_y | ||
down = 0 | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
result, object_position_local = position_local.PositionLocal.create( | ||
north, | ||
east, | ||
down, | ||
) | ||
if not result: | ||
self.__logger.warning( | ||
f"Could not convert ObjectInWorld to PositionLocal:\object in world: {object_in_world}" | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
return False, None | ||
|
||
result, object_in_world_global = ( | ||
local_global_conversion.position_global_from_position_local( | ||
self.__home_position, object_position_local | ||
) | ||
) | ||
|
||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if not result: | ||
# Log nothing if at least one of the conversions failed | ||
self.__logger.warning( | ||
f"drone_position_global_from_local conversion failed:\nhome_position: {self.__home_position}\ndrone_position_local: {object_position_local}" | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
return False, None | ||
|
||
objects_in_world_global.append(object_in_world_global) | ||
|
||
timestamp = time.time() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this required? |
||
self.__logger.info(f"{timestamp}: {objects_in_world_global}") | ||
|
||
return True, objects_in_world |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
""" | ||
Logs data and forwards it. | ||
""" | ||
|
||
import os | ||
import pathlib | ||
|
||
from . import communications | ||
from utilities.workers import queue_proxy_wrapper | ||
from utilities.workers import worker_controller | ||
from ..common.modules.logger import logger | ||
|
||
|
||
def communications_worker( | ||
home_position_queue: queue_proxy_wrapper.QueueProxyWrapper, | ||
input_queue: queue_proxy_wrapper.QueueProxyWrapper, | ||
output_queue: queue_proxy_wrapper.QueueProxyWrapper, | ||
controller: worker_controller.WorkerController, | ||
) -> None: | ||
""" | ||
Worker process. | ||
|
||
home_position: get home_position for init | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
|
||
worker_name = pathlib.Path(__file__).stem | ||
process_id = os.getpid() | ||
result, local_logger = logger.Logger.create(f"{worker_name}_{process_id}", True) | ||
if not result: | ||
print("ERROR: Worker failed to create logger") | ||
return | ||
|
||
# Get Pylance to stop complaining | ||
assert local_logger is not None | ||
|
||
local_logger.info("Logger initialized", True) | ||
|
||
# Get home position | ||
home_position = home_position_queue.queue.get() | ||
Xierumeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
local_logger.info(f"Home position received: {home_position}", True) | ||
|
||
result, comm = communications.Communications.create(home_position, local_logger) | ||
if not result: | ||
local_logger.error("Worker failed to create class object", True) | ||
return | ||
|
||
# Get Pylance to stop complaining | ||
assert comm is not None | ||
|
||
while not controller.is_exit_requested(): | ||
controller.check_pause() | ||
|
||
result, value = comm.run(input_queue.queue.get()) | ||
if not result: | ||
continue | ||
|
||
output_queue.queue.put(value) |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be in a separate PR in repository common. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please delete this. Evan or I will move it to post-processing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
""" | ||
Convert log file to KML file. | ||
""" | ||
|
||
import pathlib | ||
import re | ||
|
||
from modules.common.modules.kml import kml_conversion | ||
from modules.common.modules import location_global | ||
|
||
|
||
def convert_log_to_kml( | ||
log_file: str, document_name_prefix: str, save_directory: str | ||
) -> "tuple[bool, pathlib.Path | None]": | ||
"""Given a log file with a specific format, return a corresponding KML file. | ||
|
||
Args: | ||
log_file (str): Path to the log file | ||
document_name_prefix (str): Prefix name for saved KML file. | ||
save_directory (str): Directory to save the KML file to. | ||
|
||
Returns: | ||
tuple[bool, pathlib.Path | None]: Returns (False, None) if function | ||
failed to execute, otherwise (True, path) where path a pathlib.Path | ||
object pointing to the KML file. | ||
""" | ||
locations = [] | ||
|
||
try: | ||
with open(log_file, "r") as f: | ||
for line in f: | ||
# find all the latitudes and longitudes within the line | ||
latitudes = re.findall(r"latitude: (-?\d+\.\d+)", line) | ||
longitudes = re.findall(r"longitude: (-?\d+\.\d+)", line) | ||
|
||
# we must find equal number of latitude and longitude numbers, | ||
# otherwise that means the log file is improperly formatted or | ||
# the script failed to detect all locations | ||
if len(latitudes) != len(longitudes): | ||
print("Number of latitudes and longitudes found are different.") | ||
print(f"# of altitudes: {len(latitudes)}, # of longitudes: {len(longitudes)}") | ||
return False, None | ||
|
||
latitudes = list(map(float, latitudes)) | ||
longitudes = list(map(float, longitudes)) | ||
|
||
for i in range(len(latitudes)): | ||
success, location = location_global.LocationGlobal.create( | ||
latitudes[i], longitudes[i] | ||
) | ||
if not success: | ||
return False, None | ||
locations.append(location) | ||
|
||
return kml_conversion.locations_to_kml(locations, document_name_prefix, save_directory) | ||
except Exception as e: | ||
print(e.with_traceback()) | ||
return False, None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove all of this and just log
logger.debug(f"clusters: {detections_in_world}")
as it is in cluster_estimation_worker?